import 'dart:math' as math; import 'package:flutter/cupertino.dart'; import 'package:tuple/tuple.dart'; import '../models/documents/attribute.dart'; import '../models/documents/document.dart'; import '../models/documents/nodes/embed.dart'; import '../models/documents/style.dart'; import '../models/quill_delta.dart'; import '../utils/diff_delta.dart'; typedef ReplaceTextCallback = bool Function(int index, int len, Object? data); typedef DeleteCallback = void Function(int cursorPosition, bool forward); class QuillController extends ChangeNotifier { QuillController({ required this.document, required TextSelection selection, bool keepStyleOnNewLine = false, this.onReplaceText, this.onDelete, }) : _selection = selection, _keepStyleOnNewLine = keepStyleOnNewLine; factory QuillController.basic() { return QuillController( document: Document(), selection: const TextSelection.collapsed(offset: 0), ); } /// Document managed by this controller. final Document document; /// Tells whether to keep or reset the [toggledStyle] /// when user adds a new line. final bool _keepStyleOnNewLine; /// Currently selected text within the [document]. TextSelection get selection => _selection; TextSelection _selection; /// Custom [replaceText] handler /// Return false to ignore the event ReplaceTextCallback? onReplaceText; /// Custom delete handler DeleteCallback? onDelete; /// Store any styles attribute that got toggled by the tap of a button /// and that has not been applied yet. /// It gets reset after each format action within the [document]. Style toggledStyle = Style(); bool ignoreFocusOnTextChange = false; /// True when this [QuillController] instance has been disposed. /// /// A safety mechanism to ensure that listeners don't crash when adding, /// removing or listeners to this instance. bool _isDisposed = false; // item1: Document state before [change]. // // item2: Change delta applied to the document. // // item3: The source of this change. Stream> get changes => document.changes; TextEditingValue get plainTextEditingValue => TextEditingValue( text: document.toPlainText(), selection: selection, ); /// Only attributes applied to all characters within this range are /// included in the result. Style getSelectionStyle() { return document .collectStyle(selection.start, selection.end - selection.start) .mergeAll(toggledStyle); } /// Returns all styles for any character within the specified text range. List