flutter-quill icon indicating copy to clipboard operation
flutter-quill copied to clipboard

[BUG BOUNTY] Can't remove style on paragraphs that are separated by a new line

Open FelixMittermeier opened this issue 1 year ago • 14 comments

Flutter Quill version

8.6.1

Steps to reproduce

The following bug is really annoying for my users. I am willing to pay 50$/€ to the person who fixes this bug in a not hacky and clean way.

Write two paragraphs (separated by a new line), select both of them (or just "select all") and apply formatting like "bold" or "italic". Then you are not able to remove the style for both paragraphs. The only way is to select each paragraph separately and then you can press the "bold" button again

169970454-68da30d1-d690-44f9-8678-4355897997dd

Expected results

The style removal should directly work also across multiple paragraphs

Actual results

Nothing happens when two paragraphs are selected and you try to remove an already applied style

FelixMittermeier avatar Nov 22 '23 19:11 FelixMittermeier

I can confirm this is happening.

jpenna avatar Nov 24 '23 21:11 jpenna

I'm experiencing the same problem (version 8.6.2). That being said, if you press the clear style button, the style is removed as expected.

mregnauld avatar Nov 25 '23 16:11 mregnauld

Hi, thank you for the report

I can confirm that the bug is not related to the QuillToolbar or any of the buttons because I already tested it with a custom toolbar that was made from scratch and I still can get the issue

The bug starts inside the file controller.dart In the function:

void formatText(int index, int len, Attribute? attribute)

And then inside the file document.dart

In the function:

Delta format(int index, int len, Attribute? attribute)

It might be in the document.dart

inside the method

Style collectStyle(int index, int len)

then:

ChildQuery queryChild(int offset)

EchoEllet avatar Nov 26 '23 01:11 EchoEllet

I can confirm the bug happened because of the way the library handles the selection in the editor and the controller

When selecting all: image

When selecting only one line: image

As you can see the isToggled state differs, because the icon buttons color will be filled if the isToggled is true

https://github.com/singerdmx/flutter-quill/assets/73608287/fca42e57-f01b-46c4-8287-dd47ea1c22c3

EchoEllet avatar Nov 26 '23 21:11 EchoEllet

Hello, I'm on mobile version trying to repro this issue but i'm not able to repro, could you provide a sample json or exact step on where this is occurring? this is what i'm doing: open the editor -> type something on the first line -> hit return to insert a blank line -> hit return again -> type something on the second line -> apply bold style, then after that i'm able to select both lines and press bold again to remove. Under what scenario are the styles not able to be removed ?

li3317 avatar Jan 06 '24 02:01 li3317

Hello, I'm on mobile version trying to repro this issue but i'm not able to repro, could you provide a sample json or exact step on where this is occurring? this is what i'm doing: open the editor -> type something on the first line -> hit return to insert a blank line -> hit return again -> type something on the second line -> apply bold style, then after that i'm able to select both lines and press bold again to remove. Under what scenario are the styles not able to be removed ?

Please take a look at my comment, the problem that the way that selection work is not working like users expected, when you select all and you have in the first line bold text, second line is empty and third also have bold text

then you will see the button selected state is false because the button is not filled and it should be true because all we have is bold text and white spaces with empty lines

EchoEllet avatar Jan 06 '24 17:01 EchoEllet

Here's the result I see on my end, i'm able to apply bold to different lines (either one by one or all at one time), then select part or all of them to remove the style and it'll remove successfully. I am seeing a different issue though, after removing the style I can't apply it back because it thinks it's already toggled.

https://github.com/singerdmx/flutter-quill/assets/46685982/ab55c43b-7078-4161-9a4d-6f7cbb580dca

https://github.com/singerdmx/flutter-quill/assets/46685982/d39c05c7-aa69-42d1-a74d-3233ebcbe02c

li3317 avatar Jan 07 '24 05:01 li3317

I think you have to add an empty line between the text, then you get the described behavior.

FelixMittermeier avatar Jan 07 '24 08:01 FelixMittermeier

Like this?

and then after clicking bold again:

li3317 avatar Jan 07 '24 20:01 li3317

@li3317 so you cannot repro it?

singerdmx avatar Jan 07 '24 20:01 singerdmx

I just tested on the latest version and can still reproduce this issue as described 👀

FelixMittermeier avatar Jan 07 '24 20:01 FelixMittermeier

@singerdmx I'm not able to. Maybe it's different platform.

li3317 avatar Jan 08 '24 02:01 li3317

I think @li3317 is on mobile and she cannot repro it

singerdmx avatar Jan 08 '24 19:01 singerdmx

This bug is so infuriating I decided to spend 5 hours to fix it The bug is at lib\src\models\documents\nodes\line.dart at line 364-367, it compares style.attributes[attr.key] != attr.value when it should actually compare style.attributes[attr.key]?.value != attr.value, I guess the reason some people can't repro it is because in some version of dart anything == (bool)true while in some version only (bool)true == (bool)true

Simply change lib\src\models\documents\nodes\line.dart at line 364-367 to the following

        if (!style.containsKey(attr.key) ||
            (style.attributes[attr.key]?.value != attr.value)) {
          excluded.add(attr);
        }

Some other related issue can be fixed by setting keepStyleOnNewLine to false, see #1775

I've also created a PR request, #1782

Wrth1 avatar Mar 22 '24 22:03 Wrth1

I forgot one thing, we also need to merge the result with rest, change the line 391- 394 to this

if (remaining > 0 && nextLine != null) {
      final rest = nextLine!.collectStyle(0, remaining);
      result = result.mergeAll(rest);
      handle(rest);
    }

Wrth1 avatar Mar 22 '24 22:03 Wrth1

This bug is so infuriating I decided to spend 5 hours to fix it The bug is at lib\src\models\documents\nodes\line.dart at line 364-367, it compares style.attributes[attr.key] != attr.value when it should actually compare style.attributes[attr.key]?.value != attr.value, I guess the reason some people can't repro it is because in some version of dart anything == (bool)true while in some version only (bool)true == (bool)true

Simply change lib\src\models\documents\nodes\line.dart at line 364-367 to the following

        if (!style.containsKey(attr.key) ||
            (style.attributes[attr.key]?.value != attr.value)) {
          excluded.add(attr);
        }

Some other related issue can be fixed by setting keepStyleOnNewLine to false, see #1775

I've also created a PR request, #1782

Thanks a lot for fixing the issue !

LucasFoulonMongai avatar Mar 25 '24 08:03 LucasFoulonMongai