From e6f600f6336cf5c478e967eebd004899f2668032 Mon Sep 17 00:00:00 2001 From: AtlasAutocode Date: Sun, 28 Jul 2024 12:50:03 -0600 Subject: [PATCH] Organize editor configurations --- example/lib/screens/simple/simple_screen.dart | 6 +- lib/src/controller/quill_controller.dart | 10 ++- .../quill_controller_configurations.dart | 5 +- .../editor/config/editor_configurations.dart | 9 +-- lib/src/editor/editor.dart | 68 ++++++++++++------- lib/src/editor/provider.dart | 19 ++++-- test/bug_fix_test.dart | 8 +-- test/editor/editor_test.dart | 11 +-- 8 files changed, 86 insertions(+), 50 deletions(-) diff --git a/example/lib/screens/simple/simple_screen.dart b/example/lib/screens/simple/simple_screen.dart index a49d48ba..8f23a663 100644 --- a/example/lib/screens/simple/simple_screen.dart +++ b/example/lib/screens/simple/simple_screen.dart @@ -23,9 +23,9 @@ class _SimpleScreenState extends State { ), Expanded( child: QuillEditor.basic( - configurations: QuillEditorConfigurations( - controller: _controller, - padding: const EdgeInsets.all(16), + controller: _controller, + configurations: const QuillEditorConfigurations( + padding: EdgeInsets.all(16), ), ), ), diff --git a/lib/src/controller/quill_controller.dart b/lib/src/controller/quill_controller.dart index 5f85b623..2f4ef071 100644 --- a/lib/src/controller/quill_controller.dart +++ b/lib/src/controller/quill_controller.dart @@ -52,10 +52,14 @@ class QuillController extends ChangeNotifier { final QuillControllerConfigurations configurations; - /// Local copy of editor configurations enables fail-safe setting from editor _initState method + /// Editor configurations + /// + /// Global default can be set in QuillControllerConfigurations. + /// Can be overridden by setting in QuillEditor ctor. + /// Fail safe: returns a default editor configuration. QuillEditorConfigurations? _editorConfigurations; - QuillEditorConfigurations? get editorConfigurations => - configurations.editorConfigurations ?? _editorConfigurations; + QuillEditorConfigurations get editorConfigurations => + _editorConfigurations ?? configurations.editorConfigurations ?? const QuillEditorConfigurations(); set editorConfigurations(QuillEditorConfigurations? value) => _editorConfigurations = value; diff --git a/lib/src/controller/quill_controller_configurations.dart b/lib/src/controller/quill_controller_configurations.dart index 86ee9bbc..b5c52493 100644 --- a/lib/src/controller/quill_controller_configurations.dart +++ b/lib/src/controller/quill_controller_configurations.dart @@ -1,8 +1,10 @@ -import '../editor/config/editor_configurations.dart'; +import '../editor/config/editor_configurations.dart' show QuillEditorConfigurations; +import '../toolbar/config/toolbar_configurations.dart'; class QuillControllerConfigurations { const QuillControllerConfigurations( {this.editorConfigurations, + this.toolbarConfigurations, this.onClipboardPaste, this.requireScriptFontFeatures = false}); @@ -10,6 +12,7 @@ class QuillControllerConfigurations { /// /// Future: will be changed to 'required final' final QuillEditorConfigurations? editorConfigurations; + final QuillToolbarConfigurations? toolbarConfigurations; /// Callback when the user pastes and data has not already been processed /// diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index 421fcc43..932092a0 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -24,7 +24,8 @@ class QuillEditorConfigurations extends Equatable { /// Important note for the maintainers /// When editing this class please update the [copyWith] function too. const QuillEditorConfigurations({ - required this.controller, + @Deprecated('controller should be passed directly to the editor - this parameter will be removed in future versions.') + this.controller, this.sharedConfigurations = const QuillSharedConfigurations(), this.scrollable = true, this.padding = EdgeInsets.zero, @@ -86,7 +87,7 @@ class QuillEditorConfigurations extends Equatable { final QuillSharedConfigurations sharedConfigurations; - final QuillController controller; + final QuillController? controller; /// The text placeholder in the quill editor final String? placeholder; @@ -97,7 +98,7 @@ class QuillEditorConfigurations extends Equatable { /// by any shortcut or keyboard operation. The text is still selectable. /// /// Defaults to `false`. Must not be `null`. - bool get readOnly => controller.readOnly; + bool get readOnly => controller?.readOnly != false; /// Override [readOnly] for checkbox. /// @@ -381,7 +382,7 @@ class QuillEditorConfigurations extends Equatable { @override List get props => [ placeholder, - controller.readOnly, + controller?.readOnly, ]; // We might use code generator like freezed but sometimes it can be limited diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 9681c515..c14bb13b 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -10,6 +10,7 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import '../common/utils/platform.dart'; +import '../controller/quill_controller.dart'; import '../document/attribute.dart'; import '../document/document.dart'; import '../document/nodes/container.dart' as container_node; @@ -120,36 +121,56 @@ abstract class RenderAbstractEditor implements TextLayoutMetrics { } class QuillEditor extends StatefulWidget { - const QuillEditor({ - required this.configurations, + +//TODO - sample code + factory QuillEditor ({ + required FocusNode focusNode, + required ScrollController scrollController, + /// Controller and configurations are required + /// + /// Prefer: use controller and pass QuillEditorConfigurations in constructor for controller (using QuillControllerConfigurations). + /// Backward compatibility: use configurations and pass QuillController in constructor for configurations. (Will be removed in future versions.) + QuillController? controller, + QuillEditorConfigurations? configurations, + }) { + controller ??= configurations?.controller; + assert (controller != null, 'controller required. Provide controller directly (preferred) or indirectly through configurations (not recommended - will be removed in future versions).'); + controller ??= QuillController(document: Document(), selection: const TextSelection.collapsed(offset: 0)); + // + controller + ..editorConfigurations = configurations + ..editorFocusNode = focusNode; + // + return QuillEditor._(focusNode: focusNode, scrollController: scrollController, controller: controller); + } + + const QuillEditor._({ required this.focusNode, required this.scrollController, - super.key, + required this.controller }); factory QuillEditor.basic({ + /// The controller for the quill editor widget of flutter quill + QuillController? controller, /// The configurations for the quill editor widget of flutter quill - required QuillEditorConfigurations configurations, + QuillEditorConfigurations? configurations, FocusNode? focusNode, ScrollController? scrollController, }) { return QuillEditor( scrollController: scrollController ?? ScrollController(), focusNode: focusNode ?? FocusNode(), - configurations: configurations.copyWith( - textSelectionThemeData: configurations.textSelectionThemeData, - autoFocus: configurations.autoFocus, - expands: configurations.expands, - padding: configurations.padding, - keyboardAppearance: configurations.keyboardAppearance, - embedBuilders: configurations.embedBuilders, - editorKey: configurations.editorKey, - ), + controller: controller, + configurations: configurations?.copyWith(), ); } + /// The controller for the quill editor widget of flutter quill + final QuillController controller; + /// The configurations for the quill editor widget of flutter quill - final QuillEditorConfigurations configurations; + QuillEditorConfigurations get configurations => controller.editorConfigurations; /// Controls whether this editor has keyboard focus. final FocusNode focusNode; @@ -167,9 +188,9 @@ class QuillEditorState extends State late EditorTextSelectionGestureDetectorBuilder _selectionGestureDetectorBuilder; - QuillEditorConfigurations get configurations { - return widget.configurations; - } + QuillController get controller => widget.controller; + + QuillEditorConfigurations get configurations => widget.configurations; @override void initState() { @@ -181,11 +202,7 @@ class QuillEditorState extends State configurations.detectWordBoundary, ); - widget.configurations.controller.editorConfigurations ??= - widget.configurations; - - final focusNode = - widget.configurations.controller.editorFocusNode ??= widget.focusNode; + final focusNode = widget.focusNode; if (configurations.autoFocus) { focusNode.requestFocus(); @@ -241,13 +258,14 @@ class QuillEditorState extends State final child = FlutterQuillLocalizationsWidget( child: QuillEditorProvider( + controller: controller, editorConfigurations: configurations, child: QuillEditorBuilderWidget( builder: configurations.builder, child: QuillRawEditor( key: _editorKey, configurations: QuillRawEditorConfigurations( - controller: configurations.controller, + controller: controller, focusNode: widget.focusNode, scrollController: widget.scrollController, scrollable: configurations.scrollable, @@ -255,7 +273,7 @@ class QuillEditorState extends State configurations.enableMarkdownStyleConversion, scrollBottomInset: configurations.scrollBottomInset, padding: configurations.padding, - readOnly: configurations.readOnly, + readOnly: controller.readOnly, checkBoxReadOnly: configurations.checkBoxReadOnly, disableClipboard: configurations.disableClipboard, placeholder: configurations.placeholder, @@ -445,7 +463,7 @@ class _QuillEditorSelectionGestureDetectorBuilder } bool _isPositionSelected(TapUpDetails details) { - if (_state.configurations.controller.document.isEmpty()) { + if (_state.controller.document.isEmpty()) { return false; } final pos = renderEditor!.getPositionForOffset(details.globalPosition); diff --git a/lib/src/editor/provider.dart b/lib/src/editor/provider.dart index 159ce1ea..2c11a0ce 100644 --- a/lib/src/editor/provider.dart +++ b/lib/src/editor/provider.dart @@ -2,15 +2,25 @@ import 'package:flutter/foundation.dart' show debugPrint, kDebugMode; import 'package:flutter/widgets.dart' show BuildContext, InheritedWidget, Widget; +import '../controller/quill_controller.dart'; import 'config/editor_configurations.dart'; class QuillEditorProvider extends InheritedWidget { - const QuillEditorProvider({ + QuillEditorProvider({ required super.child, - required this.editorConfigurations, + /// Controller and configurations are required but should only be provided from one. + /// + /// Passing the controller as part of configurations is being deprecated and will be removed in the future. + /// Prefer: use controller and set QuillEditorConfigurations in the controller. + /// Current: use configurations and pass QuillController in constructor for configurations. + QuillController? controller, + @Deprecated('editorConfigurations are no longer needed and will be removed in future versions. Set configurations in the controller') + QuillEditorConfigurations? editorConfigurations, super.key, - }); + }) : editorConfigurations = editorConfigurations ?? controller?.editorConfigurations ?? QuillEditorConfigurations(controller: controller!), + controller = controller ?? editorConfigurations?.controller ?? QuillController.basic(); + final QuillController controller; final QuillEditorConfigurations editorConfigurations; @override @@ -52,8 +62,9 @@ class QuillEditorProvider extends InheritedWidget { required QuillEditorProvider value, required Widget child, }) { + value.controller.editorConfigurations = value.editorConfigurations; return QuillEditorProvider( - editorConfigurations: value.editorConfigurations, + controller: value.controller, child: child, ); } diff --git a/test/bug_fix_test.dart b/test/bug_fix_test.dart index 5834b714..42f5a93e 100644 --- a/test/bug_fix_test.dart +++ b/test/bug_fix_test.dart @@ -56,9 +56,7 @@ void main() { setUp(() { controller = QuillController.basic(); editor = QuillEditor.basic( - configurations: QuillEditorConfigurations( - controller: controller, - ), + controller: controller, ); }); @@ -142,8 +140,8 @@ void main() { home: QuillEditor( focusNode: FocusNode(), scrollController: ScrollController(), - configurations: QuillEditorConfigurations( - controller: controller, + controller: controller, + configurations: const QuillEditorConfigurations( autoFocus: true, expands: true, ), diff --git a/test/editor/editor_test.dart b/test/editor/editor_test.dart index 4e3a79f6..f95ebfcf 100644 --- a/test/editor/editor_test.dart +++ b/test/editor/editor_test.dart @@ -24,9 +24,9 @@ void main() { await tester.pumpWidget( MaterialApp( home: QuillEditor.basic( + controller: controller, // ignore: avoid_redundant_argument_values - configurations: QuillEditorConfigurations( - controller: controller, + configurations: const QuillEditorConfigurations( // ignore: avoid_redundant_argument_values ), ), @@ -44,8 +44,8 @@ void main() { home: QuillEditor( focusNode: FocusNode(), scrollController: ScrollController(), + controller: controller, configurations: QuillEditorConfigurations( - controller: controller, // ignore: avoid_redundant_argument_values autoFocus: true, expands: true, @@ -116,9 +116,9 @@ void main() { home: QuillEditor( focusNode: FocusNode(), scrollController: ScrollController(), + controller: controller, // ignore: avoid_redundant_argument_values configurations: QuillEditorConfigurations( - controller: controller, // ignore: avoid_redundant_argument_values autoFocus: true, expands: true, @@ -146,7 +146,8 @@ void main() { await tester.pumpWidget( MaterialApp( home: QuillEditor.basic( - configurations: QuillEditorConfigurations(controller: controller), + controller: controller, + configurations: const QuillEditorConfigurations(), focusNode: editorFocusNode, ), ),