diff --git a/lib/src/models/config/editor/editor_configurations.dart b/lib/src/models/config/editor/editor_configurations.dart index d6a4ecb1..74fb7fa4 100644 --- a/lib/src/models/config/editor/editor_configurations.dart +++ b/lib/src/models/config/editor/editor_configurations.dart @@ -33,6 +33,7 @@ class QuillEditorConfigurations extends Equatable { this.expands = false, this.placeholder, this.readOnly = false, + this.disableClipboard = false, this.textSelectionThemeData, this.showCursor, this.paintCursorAboveText, @@ -92,6 +93,14 @@ class QuillEditorConfigurations extends Equatable { /// Defaults to `false`. Must not be `null`. final bool readOnly; + /// Disable Clipboard features + /// + /// when this is set to `true` clipboard can not be used + /// this disables the clipboard notification for requesting permissions + /// + /// Defaults to `false`. Must not be `null`. + final bool disableClipboard; + /// Whether this editor should create a scrollable container for its content. /// /// When set to `true` the editor's height can be controlled by [minHeight], @@ -342,6 +351,7 @@ class QuillEditorConfigurations extends Equatable { QuillController? controller, String? placeholder, bool? readOnly, + bool? disableClipboard, bool? scrollable, double? scrollBottomInset, EdgeInsetsGeometry? padding, @@ -389,6 +399,7 @@ class QuillEditorConfigurations extends Equatable { controller: controller ?? this.controller, placeholder: placeholder ?? this.placeholder, readOnly: readOnly ?? this.readOnly, + disableClipboard: disableClipboard ?? this.disableClipboard, scrollable: scrollable ?? this.scrollable, scrollBottomInset: scrollBottomInset ?? this.scrollBottomInset, padding: padding ?? this.padding, diff --git a/lib/src/models/config/raw_editor/raw_editor_configurations.dart b/lib/src/models/config/raw_editor/raw_editor_configurations.dart index abe92a04..65342949 100644 --- a/lib/src/models/config/raw_editor/raw_editor_configurations.dart +++ b/lib/src/models/config/raw_editor/raw_editor_configurations.dart @@ -50,6 +50,7 @@ class QuillRawEditorConfigurations extends Equatable { this.scrollable = true, this.padding = EdgeInsets.zero, this.readOnly = false, + this.disableClipboard = false, this.placeholder, this.onLaunchUrl, this.contextMenuBuilder = defaultContextMenuBuilder, @@ -99,6 +100,14 @@ class QuillRawEditorConfigurations extends Equatable { /// Defaults to false. Must not be null. final bool readOnly; + /// Disable Clipboard features + /// + /// when this is set to true clipboard can not be used + /// this disables the clipboard notification for requesting permissions + /// + /// Defaults to false. Must not be null. + final bool disableClipboard; + final String? placeholder; /// Callback which is triggered when the user wants to open a URL from diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index c2f4d982..e66d91b9 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -235,6 +235,7 @@ class QuillEditorState extends State scrollBottomInset: configurations.scrollBottomInset, padding: configurations.padding, readOnly: configurations.readOnly, + disableClipboard: configurations.disableClipboard, placeholder: configurations.placeholder, onLaunchUrl: configurations.onLaunchUrl, contextMenuBuilder: showSelectionToolbar diff --git a/lib/src/widgets/others/text_selection.dart b/lib/src/widgets/others/text_selection.dart index efcaa86b..cb9463a6 100644 --- a/lib/src/widgets/others/text_selection.dart +++ b/lib/src/widgets/others/text_selection.dart @@ -70,8 +70,8 @@ class EditorTextSelectionOverlay { required this.debugRequiredFor, required this.selectionCtrls, required this.selectionDelegate, - required this.clipboardStatus, required this.contextMenuBuilder, + this.clipboardStatus, this.onSelectionHandleTapped, this.dragStartBehavior = DragStartBehavior.start, this.handlesVisible = false, @@ -82,11 +82,11 @@ class EditorTextSelectionOverlay { // our listener being created // we won't know the status unless there is forced update // i.e. occasionally no paste - if (!kIsWeb) { + if (clipboardStatus != null && !kIsWeb) { // Web - esp Safari Mac/iOS has security measures in place that restrict // cliboard status checks w/o direct user interaction. So skip this // for web - clipboardStatus.update(); + clipboardStatus!.update(); } } @@ -172,7 +172,7 @@ class EditorTextSelectionOverlay { /// /// Useful because the actual value of the clipboard can only be checked /// asynchronously (see [Clipboard.getData]). - final ClipboardStatusNotifier clipboardStatus; + final ClipboardStatusNotifier? clipboardStatus; /// A pair of handles. If this is non-null, there are always 2, though the /// second is hidden when the selection is collapsed. diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 80c1569f..1798722c 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -97,13 +97,7 @@ class QuillRawEditorState extends EditorState String get pastePlainText => _pastePlainText; String _pastePlainText = ''; - // Web - esp Safari Mac/iOS has security measures in place that restrict - // cliboard status checks w/o direct user interaction. Initializing the - // ClipboardStatusNotifier with a default value of unknown will cause the - // clipboard status to be checked w/o user interaction which fails. Default - // to pasteable for web. - final ClipboardStatusNotifier _clipboardStatus = ClipboardStatusNotifier( - value: kIsWeb ? ClipboardStatus.pasteable : ClipboardStatus.unknown); + ClipboardStatusNotifier? _clipboardStatus; final LayerLink _toolbarLayerLink = LayerLink(); final LayerLink _startHandleLayerLink = LayerLink(); final LayerLink _endHandleLayerLink = LayerLink(); @@ -325,7 +319,8 @@ class QuillRawEditorState extends EditorState /// Copied from [EditableTextState]. List get contextMenuButtonItems { return EditableText.getEditableButtonItems( - clipboardStatus: _clipboardStatus.value, + clipboardStatus: + (_clipboardStatus != null) ? _clipboardStatus!.value : null, onCopy: copyEnabled ? () => copySelection(SelectionChangedCause.toolbar) : null, @@ -528,6 +523,16 @@ class QuillRawEditorState extends EditorState ), ); + if (!widget.configurations.disableClipboard) { + // Web - esp Safari Mac/iOS has security measures in place that restrict + // cliboard status checks w/o direct user interaction. Initializing the + // ClipboardStatusNotifier with a default value of unknown will cause the + // clipboard status to be checked w/o user interaction which fails. Default + // to pasteable for web. + _clipboardStatus = ClipboardStatusNotifier( + value: kIsWeb ? ClipboardStatus.pasteable : ClipboardStatus.unknown); + } + if (widget.configurations.scrollable) { /// Since [SingleChildScrollView] does not implement /// `computeDistanceToActualBaseline` it prevents the editor from @@ -1122,8 +1127,9 @@ class QuillRawEditorState extends EditorState @override void initState() { super.initState(); - - _clipboardStatus.addListener(_onChangedClipboardStatus); + if (_clipboardStatus != null) { + _clipboardStatus!.addListener(_onChangedClipboardStatus); + } controller.addListener(_didChangeTextEditingValueListener); @@ -1277,9 +1283,11 @@ class QuillRawEditorState extends EditorState controller.removeListener(_didChangeTextEditingValueListener); widget.configurations.focusNode.removeListener(_handleFocusChanged); _cursorCont.dispose(); - _clipboardStatus - ..removeListener(_onChangedClipboardStatus) - ..dispose(); + if (_clipboardStatus != null) { + _clipboardStatus! + ..removeListener(_onChangedClipboardStatus) + ..dispose(); + } super.dispose(); }