diff --git a/CHANGELOG.md b/CHANGELOG.md index affde4e1..d5e93d88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ## 9.0.2-dev.1 * Add configurations for the new dropdown `QuillToolbarSelectHeaderStyleButton`, you can use the orignal one or this +* Fix the [issue](https://github.com/singerdmx/flutter-quill/issues/1119) when enter is pressed, all font settings is lost ## 9.0.2-dev * **Breaking change** Remove the spacer widget, removed the controller option for each button diff --git a/lib/src/widgets/quill/quill_controller.dart b/lib/src/widgets/quill/quill_controller.dart index 11c8951b..41300cb2 100644 --- a/lib/src/widgets/quill/quill_controller.dart +++ b/lib/src/widgets/quill/quill_controller.dart @@ -1,9 +1,10 @@ import 'dart:math' as math; -import 'package:flutter/services.dart'; +import 'package:flutter/services.dart' show ClipboardData, Clipboard; import 'package:flutter/widgets.dart'; import 'package:html2md/html2md.dart' as html2md; import 'package:markdown/markdown.dart' as md; +import 'package:meta/meta.dart'; import '../../../markdown_quill.dart'; import '../../../quill_delta.dart'; @@ -16,6 +17,7 @@ import '../../models/structs/doc_change.dart'; import '../../models/structs/image_url.dart'; import '../../models/structs/offset_value.dart'; import '../../utils/delta.dart'; +import '../toolbar/buttons/toggle_style_button.dart'; typedef ReplaceTextCallback = bool Function(int index, int len, Object? data); typedef DeleteCallback = void Function(int cursorPosition, bool forward); @@ -24,14 +26,13 @@ class QuillController extends ChangeNotifier { QuillController({ required Document document, required TextSelection selection, - bool keepStyleOnNewLine = false, + this.keepStyleOnNewLine = true, this.onReplaceText, this.onDelete, this.onSelectionCompleted, this.onSelectionChanged, }) : _document = document, - _selection = selection, - _keepStyleOnNewLine = keepStyleOnNewLine; + _selection = selection; factory QuillController.basic() { return QuillController( @@ -54,6 +55,7 @@ class QuillController extends ChangeNotifier { notifyListeners(); } + @experimental void setContents( Delta delta, { ChangeSource changeSource = ChangeSource.local, @@ -68,6 +70,9 @@ class QuillController extends ChangeNotifier { notifyListeners(); } + // Thoses are the values that the user selects and not the one + // from the current line + /// The current font family, null to use the default one String? _selectedFontFamily; @@ -88,9 +93,20 @@ class QuillController extends ChangeNotifier { _selectedFontSize = newFontSize; } + /// For the [QuillToolbarToggleStyleButton] + final Map _selectedStyles = {}; + + /// For the [QuillToolbarToggleStyleButton] + Map get selectedStyles => _selectedStyles; + + /// For the [QuillToolbarToggleStyleButton] + void selectStyle(Attribute attribute, bool value) { + _selectedStyles[attribute] = value; + } + /// Tells whether to keep or reset the [toggledStyle] /// when user adds a new line. - final bool _keepStyleOnNewLine; + final bool keepStyleOnNewLine; /// Currently selected text within the [document]. TextSelection get selection => _selection; @@ -269,6 +285,7 @@ class QuillController extends ChangeNotifier { Object? data, TextSelection? textSelection, { bool ignoreFocus = false, + bool shouldNotifyListeners = true, }) { assert(data is String || data is Embeddable); @@ -324,7 +341,9 @@ class QuillController extends ChangeNotifier { if (ignoreFocus) { ignoreFocusOnTextChange = true; } - notifyListeners(); + if (shouldNotifyListeners) { + notifyListeners(); + } ignoreFocusOnTextChange = false; } @@ -342,7 +361,12 @@ class QuillController extends ChangeNotifier { }); } - void formatText(int index, int len, Attribute? attribute) { + void formatText( + int index, + int len, + Attribute? attribute, { + bool shouldNotifyListeners = true, + }) { if (len == 0 && attribute!.isInline && attribute.key != Attribute.link.key) { @@ -361,11 +385,19 @@ class QuillController extends ChangeNotifier { if (selection != adjustedSelection) { _updateSelection(adjustedSelection, ChangeSource.local); } - notifyListeners(); + if (shouldNotifyListeners) { + notifyListeners(); + } } - void formatSelection(Attribute? attribute) { - formatText(selection.start, selection.end - selection.start, attribute); + void formatSelection(Attribute? attribute, + {bool shouldNotifyListeners = true}) { + formatText( + selection.start, + selection.end - selection.start, + attribute, + shouldNotifyListeners: shouldNotifyListeners, + ); } void moveCursorToStart() { @@ -447,7 +479,7 @@ class QuillController extends ChangeNotifier { _selection = selection.copyWith( baseOffset: math.min(selection.baseOffset, end), extentOffset: math.min(selection.extentOffset, end)); - if (_keepStyleOnNewLine) { + if (keepStyleOnNewLine) { final style = getSelectionStyle(); final ignoredStyles = style.attributes.values.where( (s) => !s.isInline || s.key == Attribute.link.key, diff --git a/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart b/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart index aeb2135e..c8c37561 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart @@ -208,12 +208,8 @@ mixin RawEditorStateTextInputClientMixin on EditorState value.selection, ); - // TODO: There is a bug here, the first character is not being formatted - if (widget.configurations.controller.selectedFontFamily != null) { - widget.configurations.controller.formatText( - diff.start, - diff.deleted.length, + widget.configurations.controller.formatSelection( Attribute.fromKeyValue( Attribute.font.key, widget.configurations.controller.selectedFontFamily, @@ -221,12 +217,8 @@ mixin RawEditorStateTextInputClientMixin on EditorState ); } - // TODO: A bug here too - if (widget.configurations.controller.selectedFontSize != null) { - widget.configurations.controller.formatText( - diff.start, - diff.deleted.length, + widget.configurations.controller.formatSelection( Attribute.fromKeyValue( Attribute.size.key, widget.configurations.controller.selectedFontSize == '0' @@ -236,6 +228,13 @@ mixin RawEditorStateTextInputClientMixin on EditorState ), ); } + // if (widget.configurations.controller.keepStyleOnNewLine) { + // widget.configurations.controller.selectedStyles.forEach((key, value) { + // if (value ?? false) { + // widget.configurations.controller.formatSelection(key); + // } + // }); + // } } } diff --git a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart index e608d161..6f7f4305 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart @@ -221,9 +221,13 @@ class QuillToolbarToggleStyleButtonState } void _toggleAttribute() { - controller.formatSelection( - _isToggled! ? Attribute.clone(widget.attribute, null) : widget.attribute, - ); + controller + ..formatSelection( + (_isToggled ?? false) + ? Attribute.clone(widget.attribute, null) + : widget.attribute, + ) + ..selectStyle(widget.attribute, _isToggled ?? false); } } @@ -249,9 +253,10 @@ Widget defaultToggleStyleButtonBuilder( : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color) : (iconTheme?.disabledIconColor ?? theme.disabledColor); return QuillToolbarIconButton( - icon: Icon(icon, size: iconSize * iconButtonFactor, color: iconColor), - isFilled: isEnabled ? isToggled == true : false, - onPressed: onPressed, - afterPressed: afterPressed, - padding: iconTheme?.padding); + icon: Icon(icon, size: iconSize * iconButtonFactor, color: iconColor), + isFilled: isEnabled ? isToggled == true : false, + onPressed: onPressed, + afterPressed: afterPressed, + padding: iconTheme?.padding, + ); }