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

fix(Text) Fix style transfer issue on a line that is not empty #9461

Merged
merged 23 commits into from
Jan 13, 2024

Conversation

asturur
Copy link
Member

@asturur asturur commented Oct 30, 2023

Motivation

Fix las bug mentioned in #9028 that adds unwanted style on previous text when we insert a new line.
This bug is also present in 5.x

image

bug after inserting a new line

image

close #9028

Description

Changes

  • when insert a new line and some text is available after the newLine we won't prestyle the char 0 of the new created line.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 30, 2023

Build Stats

file / KB (diff) bundled minified
fabric 907.665 (+0.214) 304.729 (+0.011)

@asturur
Copy link
Member Author

asturur commented Oct 30, 2023

This in theory removes the last known style text bug with typing.
I'm sure that with some combination of copy paste we can trigger some uncovered case

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.

I really do not like these patches
As I said and PRed the problem is deeper so you will keep finding these annoying edge cases
Reviewing this will take time

Copy link
Contributor

Choose a reason for hiding this comment

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

there is another major bug here
fabric.js should be in the first line and not break, this is a regression I am seeing at work as well

Copy link
Member Author

Choose a reason for hiding this comment

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

this is splitByGrapheme true so this will not take care of words, will just wraps whenever it feels it has to wrap.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you look at v5 that is not the same I think

Copy link
Contributor

Choose a reason for hiding this comment

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

Setting split should split the word up (as in the other split true tests). I wondered about the word grapheme since this is really a Unicode character split but apparently there's different takes on what's considered a character vs. grapheme. I think the question here is what was broken in v5 that was considered "working" and what is actually a regression.

Copy link
Member Author

Choose a reason for hiding this comment

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

splitByGrapheme is an option that was introduced for languages that do not use spaces to break text.
It doesn't split by unicode character but by grapheme clusters, if the appropriate splitter is provided.
Otherwise it splits with the rudimental grapheme splitter of fabricJS.
a grapheme can be made of more unicode codepoints/characters glued together. In our example it doesn't happen.

Copy link
Member Author

Choose a reason for hiding this comment

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

regarding ' I think the question here is what was broken in v5 that was considered "working" and what is actually a regression.' i think nothing broken in v5 was considered working for styles.
This bug wasn't listed anywhere and i didn't know or remember of it.

@asturur
Copy link
Member Author

asturur commented Nov 3, 2023

I really do not like these patches As I said and PRed the problem is deeper so you will keep finding these annoying edge cases Reviewing this will take time

As i said, we don't refactor to fix bugs, and moreover we are not refactoring text anytime soon.
If we want to improve text code we need to spin up a new class that will slowly replace the older, so small dumb fixes to the current text code is all we can do.

@asturur
Copy link
Member Author

asturur commented Nov 3, 2023

Anyway there is no rush here to merge this, this particular bug is here since before 5.

const originalLineLength = this._unwrappedTextLines[lineIndex].length;
const isEndOfLine = originalLineLength === charIndex;

let someStyleIsCarringOver = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you mean someStyleIsCarryingOver?

Copy link
Contributor

Choose a reason for hiding this comment

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

@gloriousjob you can use the suggestion markdown
image

Suggested change
let someStyleIsCarringOver = false;
let someStyleIsCarryingOver = false;

@gloriousjob
Copy link
Contributor

Just checking but the example shows splitting a styled, then unstyled into two lines. Is the reverse handled as well (i.e., foo is unstyled, bar is red, and splitting doesn't make the b unstyled)?

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.

Playwright is a very very good tool that makes reviewing this PR simple
However the test passes on current master even though it is broken, please make it break

await page.mouse.up();
// we remove them because space is finishing
await canvasUtil.press('Backspace');
// lets click where style end to show that we can add new line without carrying over
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest usign test.step to organize the test instead of leaving comments
It is more clear when reading and when looking at test results

Copy link
Contributor

@ShaMan123 ShaMan123 Nov 4, 2023

Choose a reason for hiding this comment

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

screenshot

85800a532aaae57a102d53213c2b8114a0cadb8e.webm

Copy link
Contributor

@ShaMan123 ShaMan123 Nov 4, 2023

Choose a reason for hiding this comment

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

Checkout src files to master
image

@@ -819,7 +820,7 @@ export abstract class ITextBehavior<
for (const index in this.styles[lineIndex]) {
const numIndex = parseInt(index, 10);
if (numIndex >= charIndex) {
somethingAdded = true;
someStyleIsCarringOver = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
someStyleIsCarringOver = true;
someStyleIsCarryingOver = true;

@@ -828,14 +829,16 @@ export abstract class ITextBehavior<
}
}
let styleCarriedOver = false;
if (somethingAdded && !isEndOfLine) {
if (someStyleIsCarringOver && !isEndOfLine) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (someStyleIsCarringOver && !isEndOfLine) {
if (someStyleIsCarryingOver && !isEndOfLine) {

@asturur
Copy link
Member Author

asturur commented Dec 7, 2023

i will add the test in master first, with steps as commented.
https://github.com/fabricjs/fabric.js/pull/9531/files?diff=unified&w=1

We are adding an extra test step to cover the bug, and we are adding a step construct between the blocks of the test.
The screenshots are slightly smaller to avoid dealing with too small percentages

@asturur
Copy link
Member Author

asturur commented Dec 7, 2023

hopefully test fail, but i wouldn't count on it.

@asturur
Copy link
Member Author

asturur commented Dec 7, 2023

so at commit 29dcc2e we have failure

@asturur
Copy link
Member Author

asturur commented Dec 7, 2023

and at commit b84e6f8 we have good test.

Locally it passes anyway, but i can't do miracles, i should redo a different test that show this particular but bigger or find a way to only have a zone of the screenshot, but i can't find an option for it.

But also this is good enough

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.

There a typos that are commented by @gloriousjob
And I cpmmented a way tp clip the snapshot and perform a more reliable diff using number of pixels instead of percentage

@@ -112,7 +112,7 @@ for (const splitByGrapheme of [true, false]) {
// and there is no style on the part of text that follows, but there is visible text.
await expect(await canvasUtil.screenshot()).toMatchSnapshot({
name: `6-after-adding-a-newline-splitByGrapheme-${splitByGrapheme}.png`,
maxDiffPixelRatio: 0.01,
maxDiffPixelRatio: 0.009,
Copy link
Contributor

Choose a reason for hiding this comment

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

await expect(page).toHaveScreenshot(`${name}.png`, {
          clip: {
            x,
            y,
            width,
            height,
          },
          maxDiffPixels, // insteadof percentage
        });

Copy link
Member Author

Choose a reason for hiding this comment

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

where is this clip in the documentation? i looked for something like this.

Copy link
Member Author

Choose a reason for hiding this comment

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

oh ok is an entirely different way to do visual comparison. the locator can't be clipped.

Copy link
Contributor

Choose a reason for hiding this comment

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

but the image can, right?

Co-authored-by: gloriousjob <gloriousjob@users.noreply.github.com>
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.

The playwright test is failing

width: 120,
height: 120,
},
maxDiffPixels: 0.029,
Copy link
Contributor

Choose a reason for hiding this comment

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

I thought this was an interger

ShaMan123
ShaMan123 previously approved these changes Dec 18, 2023
Copy link
Contributor

Coverage after merging text-new-line-style-fix into master will be

82.81%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
index.node.ts7.69%100%0%14.29%17, 20, 23, 35, 38, 41
src
   ClassRegistry.ts100%100%100%100%
   Collection.ts94.85%94.83%87.10%97.14%109, 112, 215–216, 241–242
   CommonMethods.ts96.55%87.50%100%100%9
   Intersection.ts100%100%100%100%
   Observable.ts87.76%85.29%87.50%89.58%134–135, 160–161, 32–33, 41, 50, 78, 89
   Point.ts100%100%100%100%
   Shadow.ts98.36%95.65%100%100%178
   cache.ts97.06%90%100%100%57
   config.ts74.14%65%66.67%82.76%131, 139, 139, 139, 139, 139–141, 152–154, 30
   constants.ts100%100%100%100%
src/LayoutManager
   LayoutManager.ts87.58%89.47%76.92%90%135–136, 138–139, 139, 139, 139, 139, 233, 291–292, 303, 46
   constants.ts100%100%100%100%
src/LayoutManager/LayoutStrategies
   ClipPathLayout.ts82.05%72.22%100%88.89%30–31, 42, 54, 57–58, 65
   FitContentLayout.ts100%100%100%100%
   FixedLayout.ts20%0%0%40%20–21, 23, 23, 23, 23, 23
   LayoutStrategy.ts86%64.71%100%96.15%36, 43, 43, 43, 51, 71–72
   utils.ts91.67%85.71%100%100%28, 34
src/Pattern
   Pattern.ts90.54%93.94%80%90.32%119, 130, 139, 32, 36
src/brushes
   BaseBrush.ts100%100%100%100%
   CircleBrush.ts0%0%0%0%108, 108, 108, 110, 112, 114–116, 118–121, 128–129, 13, 136, 138, 23–24, 32–36, 40–44, 51–54, 62–66, 68, 76, 76, 76, 76, 76–77, 79, 79, 79–82, 84, 92–93, 95, 97–99
   PatternBrush.ts97.06%87.50%100%100%21
   PencilBrush.ts91.06%82.35%100%93.81%122–123, 152, 152–154, 176, 176, 276, 280, 285–286, 68–69, 84–85
   SprayBrush.ts0%0%0%0%107, 107, 107, 107, 107–108, 110–111, 118–119, 121, 123–127, 136, 140–141, 141, 148, 148, 148–151, 153–156, 160–161, 163, 165–168, 17, 171, 178–179, 18, 181, 183–184, 186, 193–194, 196–197, 20, 200, 200, 207, 207, 21, 211, 22, 22, 22–24, 28, 32, 39, 46, 53, 60, 67, 84–86, 94–96, 98–99
src/canvas
   Canvas.ts78.91%76.99%82.76%79.72%1005–1006, 1006, 1006–1007, 1013, 1015, 1043–1045, 1048–1049, 1053–1054, 1165–1167, 1170–1171, 1244, 1356, 1477, 158, 183, 289, 289–294, 299, 322–323, 328–333, 353, 353, 353–354, 354, 354–355, 363, 368–369, 369, 369–370, 372, 381, 387–388, 388, 388, 42, 431, 439, 443, 443, 443–444, 446, 46, 528–529, 529, 529–530, 536, 536, 536–538, 558, 560, 560, 560–561, 561, 561, 564, 564, 564–565, 568, 577–578, 580–581, 583, 583–584, 586–587, 599–600, 600, 600–601, 603–608, 614, 621, 658, 658, 658, 660, 662–667, 673, 679, 679, 679–680, 682, 685, 690, 703, 731, 783–784, 784, 784, 784, 784, 784, 787–788, 791, 791–793, 796–797, 879, 886, 886, 886, 899, 932, 953–954, 970–971, 971, 971–973, 976–977, 977, 977, 979, 987, 987, 987–989, 989, 989, 996–997
   CanvasOptions.ts100%100%100%100%
   SelectableCanvas.ts93.44%91.80%94.34%94.57%1004, 1012, 1123, 1125, 1127–1128, 1198–1199, 460–461, 463–464, 464, 464, 513–514, 591, 596, 666, 671–672, 699–700, 760–761, 766–770, 772, 931, 931–932, 935, 955, 955
   StaticCanvas.ts96.53%93.09%98.92%98.29%1019, 1029, 1080–1082, 1085, 1120–1121, 1197, 1206, 1206, 1210, 1210, 1257–1258, 178–179, 195, 559, 571–572, 902–903, 903, 903–904
   StaticCanvasOptions.ts100%100%100%100%
   TextEditingManager.ts86%71.43%91.67%91.67%17, 17, 17–18, 18, 18
src/canvas/DOMManagers
   CanvasDOMManager.ts95.52%70%100%100%21–22, 29
   StaticCanvasDOMManager.ts97.50%88.89%100%100%33
   util.ts86.67%80.56%83.33%93.94%14, 26, 63–64, 67, 67, 74, 93–94
src/color
   Color.ts94.96%91.67%96.30%96.05%233, 258–259, 267–268, 48
   color_map.ts100%100%100%100%
   constants.ts100%100%100%100%
   util.ts85.71%76.92%100%89.74%55–56, 56, 58, 58, 58–59, 61–62, 89
src/controls
   Control.ts94.44%93.10%91.67%96.77%183, 249, 354
   changeWidth.ts100%100%100%100%
   commonControls.ts100%100%100%100%
   controlRendering.ts81.63%78%100%84.78%106, 111, 121, 121, 45, 50, 61, 61, 65–72, 81–82
   drag.ts100%100%100%100%
   fireEvent.ts88.89%75%100%100%13
   polyControl.ts10.87%0%0%16.13%114, 114, 114, 114, 114, 116–119, 119, 122, 129, 24–26, 50–52, 58–59, 61, 71, 77–79, 79, 81, 84, 86, 90–92, 94, 99
   rotate.ts19.57%12.50%50%21.43%41, 45, 51, 51, 51–52, 55–57, 59, 59, 59, 59, 59–61, 61, 61–63, 65, 65, 65–67, 67, 67–68, 73, 73, 73–74,

@asturur asturur merged commit 5e9299b into master Jan 13, 2024
21 of 22 checks passed
@asturur asturur deleted the text-new-line-style-fix branch January 13, 2024 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG]: text style onInput
3 participants