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

What's the correct way to abort an insertion?

Open oligazar opened this issue 1 year ago • 8 comments

Is there an existing issue for this?

The question

I need to implement text length limit in quill editor. As there's no way to set the limit afaik, I created an InsertRule, which should not allow to insert data into the document if the length limit is reached. The code looks like this

@override
  Delta? applyRule(
    Delta document,
    int index, {
    int? len,
    Object? data,
    Attribute<dynamic>? attribute,
  }) {
    final dataLength = data is String ? data.length : 0;
    final shouldAbort = textLength + dataLength > contentLengthLimit;
    if (shouldAbort) {
      // abort the changes
      return Delta();
    }
    // allow the changes
    return null;
  }

To avoid the document change an empty Delta is returned. But this results in Failed assertion

The following assertion was thrown during method call TextInputClient.updateEditingState:
'package:flutter_quill/src/models/documents/document.dart': Failed assertion: line 309 pos 12: 'delta.isNotEmpty': is not true.

So what would be the intended way of implementing this?

oligazar avatar Jun 29 '24 06:06 oligazar

Delta always need a new line at last operation. If you want a empty document, just clear it, and insert a new line. All should be fine

CatHood0 avatar Jun 29 '24 07:06 CatHood0

@CatHood0 But I don't need a new line. I need to leave the document exactly the way it was before

oligazar avatar Jun 29 '24 07:06 oligazar

The new line is just a necessary thing, and it doesn't have any effect on the view. If you still want to maintain your document empty, we cannot do nothing about it. Delta works of that way

CatHood0 avatar Jun 29 '24 08:06 CatHood0

@CatHood0 can you please give me a code example? Because I'm trying to do it like this, and it's definitely inserting a new line, which a want to avoid

if (shouldAbort) {
      if (dataLength > 1) {
        AppToasts.info(
          message: 'Unable to insert.\nContent length limit is reached.',
        ).show(get<AppRouter>().navigatorContext!);
      }
      return Delta()
        ..retain(index)
        ..insert('\n');
    }

oligazar avatar Jun 29 '24 08:06 oligazar

Which version are you using? Could be an error from the version

if (shouldAbort) { if (dataLength > 1) { AppToasts.info( message: 'Unable to insert.\nContent length limit is reached.', ).show(get<AppRouter>().navigatorContext!); } return Delta() ..retain(index) ..insert('\n'); }

It looks like if the Delta just don't do the insertion. I think could be or a version error, or a wrong logic implementation at your code

This is the line that throws the error

assert(delta.isNotEmpty)

And this is how delta verify if your operations aren't empty

/// Returns `true` if this delta is not empty.
bool get isNotEmpty => operations.isNotEmpty;

I suggest first watch if the delta is inserting your new line as should be

CatHood0 avatar Jun 29 '24 09:06 CatHood0

You're correct, returning Delta() fails the assertion as it doesn't have operations. You suggested inserting a new line saying it will leave the document as it was before. I did it like this:

eturn Delta()
..retain(index)
..insert('\n');

But it's inserting a new line. How can I avoid any unwanted changes to the document not getting any exceptions?

Maybe it's better to create PR, replacing assert(delta.isNotEmpty) with if (delta.isEmpty) return;? Would that work?

oligazar avatar Jun 29 '24 14:06 oligazar

@ellet0 can you see this?

CatHood0 avatar Jun 29 '24 17:06 CatHood0

@ellet0 can you see this?

I'm unfamiliar with the code that's related to how Delta rules work, I think we could provide an option to ignore this rule of a line at the end. It doesn't confirm to Quill though. Developers expect to have the compatible underline data with similar behavior, so I would suggest having the current rule as default.

The issue of having one line in the last delta operation, it shouldn't change the view or user experience. I remember there was a static const that represents an empty document that already has one line in the last operation.

EchoEllet avatar Jun 29 '24 18:06 EchoEllet

Does this issue still persists? If it does, please reopen this issue

CatHood0 avatar Sep 21 '24 03:09 CatHood0

@oligazar Can you confirm if this still an issue?

EchoEllet avatar Sep 21 '24 13:09 EchoEllet