singerdmx / flutter-quill

Rich text editor for Flutter
https://pub.dev/packages/flutter_quill
MIT License
2.52k stars 809 forks source link

Dragging empty text generates an error message #2159

Closed cgzcgb closed 9 hours ago

cgzcgb commented 2 weeks ago

Is there an existing issue for this?

Flutter Quill version

10.4.0

Steps to reproduce

1.

QuillEditor.basic(
  scrollController: logic.scrollEditController,
  focusNode: logic.editFocusNode,
  configurations: QuillEditorConfigurations(
     scrollable: true,
     autoFocus: false,
     placeholder: '(-)',
     textSelectionThemeData: TextSelectionThemeData(
       selectionHandleColor: appTheme.color.defaultBrushFor(
       theme.brightness,
     ),
  ),
)

2.Click on QuillEditor Focus

3.Hold down the left mouse button and drag the mouse

Expected results

There shouldn't be any changes

Actual results

======== Exception caught by gesture ===============================================================
The following RangeError was thrown while handling a gesture:
RangeError (index): Invalid value: Only valid value is 0: 1

When the exception was thrown, this was the stack: 
#0      _StringBase.[] (dart:core-patch/string_patch.dart:274:41)
#1      getDiff (package:flutter_quill/src/delta/delta_diff.dart:43:36)
#2      RawEditorStateSelectionDelegateMixin.textEditingValue= (package:flutter_quill/src/editor/raw_editor/raw_editor_state_selection_delegate_mixin.dart:21:18)
#3      RawEditorStateSelectionDelegateMixin.userUpdateTextEditingValue (package:flutter_quill/src/editor/raw_editor/raw_editor_state_selection_delegate_mixin.dart:110:5)
#4      EditorTextSelectionGestureDetectorBuilder._extendSelection (package:flutter_quill/src/editor/widgets/delegate.dart:214:13)
#5      EditorTextSelectionGestureDetectorBuilder.onDragSelectionUpdate (package:flutter_quill/src/editor/widgets/delegate.dart:919:14)
#6      _EditorTextSelectionGestureDetectorState._handleDragUpdate (package:flutter_quill/src/editor/widgets/text/text_selection.dart:998:35)
#7      BaseTapAndDragGestureRecognizer._checkDragUpdate.<anonymous closure> (package:flutter/src/gestures/tap_and_drag.dart:1275:65)
#8      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:351:24)
#9      BaseTapAndDragGestureRecognizer._checkDragUpdate (package:flutter/src/gestures/tap_and_drag.dart:1275:9)
#10     BaseTapAndDragGestureRecognizer.handleEvent (package:flutter/src/gestures/tap_and_drag.dart:1098:9)
#11     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#12     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#13     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:633:13)
#14     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#15     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#16     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:501:19)
#17     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:481:22)
#18     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:450:11)
#19     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:426:7)
#20     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:389:5)
#21     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:336:7)
#22     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:305:9)
#23     _invoke1 (dart:ui/hooks.dart:328:13)
#24     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:442:7)
#25     _dispatchPointerDataPacket (dart:ui/hooks.dart:262:31)
Handler: "onDragUpdate"
Recognizer: TapAndPanGestureRecognizer#90a8a
  debugOwner: _EditorTextSelectionGestureDetectorState#d53c9
====================================================================================================

Code sample

Code sample ```dart [Paste your code here] ```

Additional Context

Screenshots / Video demonstration [Upload media here]
Logs ```console [Paste your logs here] ```
CatHood0 commented 2 weeks ago

This part has an unsafe operation.

/* Get diff operation between old text and new text */
Diff getDiff(String oldText, String newText, int cursorPosition) {
  var end = oldText.length;
  final delta = newText.length - end;
  for (final limit = math.max(0, cursorPosition - delta);
      end > limit && oldText[end - 1] == newText[end + delta - 1];
      end--) {}
  var start = 0;
  for (final startLimit = cursorPosition - math.max(0, delta);
      start < startLimit && oldText[start] == newText[start];
      start++) {}
  final deleted = (start >= end) ? '' : oldText.substring(start, end);
  final inserted = newText.substring(start, end + delta);
  return Diff(
    start: start,
    deleted: deleted,
    inserted: inserted,
  );
}
singerdmx commented 2 weeks ago

Yeah, also the performance is terrible

CatHood0 commented 2 weeks ago

Yeah, also the performance is terrible

Same. Using the magnifier literally can crash a slower device. I'm trying to know where or how i can improve some of these parts.