Organize editor configurations

pull/2078/head
AtlasAutocode 9 months ago
parent 6978512b89
commit e6f600f633
  1. 6
      example/lib/screens/simple/simple_screen.dart
  2. 10
      lib/src/controller/quill_controller.dart
  3. 5
      lib/src/controller/quill_controller_configurations.dart
  4. 9
      lib/src/editor/config/editor_configurations.dart
  5. 68
      lib/src/editor/editor.dart
  6. 19
      lib/src/editor/provider.dart
  7. 8
      test/bug_fix_test.dart
  8. 11
      test/editor/editor_test.dart

@ -23,9 +23,9 @@ class _SimpleScreenState extends State<SimpleScreen> {
),
Expanded(
child: QuillEditor.basic(
configurations: QuillEditorConfigurations(
controller: _controller,
padding: const EdgeInsets.all(16),
controller: _controller,
configurations: const QuillEditorConfigurations(
padding: EdgeInsets.all(16),
),
),
),

@ -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;

@ -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
///

@ -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<Object?> get props => [
placeholder,
controller.readOnly,
controller?.readOnly,
];
// We might use code generator like freezed but sometimes it can be limited

@ -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<QuillEditor>
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<QuillEditor>
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<QuillEditor>
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<QuillEditor>
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);

@ -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,
);
}

@ -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,
),

@ -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,
),
),

Loading…
Cancel
Save