From c6636b73dbecb8e9e7f5e61f5439f7afe20054d4 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Sun, 15 Sep 2024 15:53:05 -0400 Subject: [PATCH 001/113] Chore: added transparent_attribue --- lib/src/document/attribute.dart | 8 ++++++++ lib/src/editor/editor.dart | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/src/document/attribute.dart b/lib/src/document/attribute.dart index 458bb9e22..8f021cb48 100644 --- a/lib/src/document/attribute.dart +++ b/lib/src/document/attribute.dart @@ -88,6 +88,8 @@ class Attribute extends Equatable { static const BackgroundAttribute background = BackgroundAttribute(null); static const PlaceholderAttribute placeholder = PlaceholderAttribute(); + + static const TransparentAttribute transparent = TransparentAttribute(); static const HeaderAttribute header = HeaderAttribute(); @@ -352,6 +354,12 @@ class PlaceholderAttribute extends Attribute { : super('placeholder', AttributeScope.inline, true); } +/// This is custom attribute for hint +class TransparentAttribute extends Attribute { + const TransparentAttribute() + : super('transparent', AttributeScope.ignore, true); +} + class HeaderAttribute extends Attribute { const HeaderAttribute({int? level}) : super('header', AttributeScope.block, level); diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 617d88fbc..e26c48cc5 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -1060,7 +1060,8 @@ class RenderEditor extends RenderEditableContainerBox // Don't change selection if the selected word is a placeholder. if (child.container.style.attributes - .containsKey(Attribute.placeholder.key)) { + .containsKey(Attribute.placeholder.key) || child.container.style.attributes + .containsKey(Attribute.transparent.key)) { return; } From 87cea7aecd980139d118f7d16888772ed0d53bfd Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Tue, 17 Sep 2024 18:13:49 -0400 Subject: [PATCH 002/113] Partial improvements --- lib/src/editor/editor.dart | 8 ++++++-- lib/src/editor/raw_editor/raw_editor_state.dart | 1 + lib/src/editor/widgets/text/text_line.dart | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index e26c48cc5..093aa190f 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -32,6 +32,7 @@ import 'widgets/box.dart'; import 'widgets/cursor.dart'; import 'widgets/delegate.dart'; import 'widgets/float_cursor.dart'; +import 'widgets/text/text_line.dart'; import 'widgets/text/text_selection.dart'; /// Base interface for editable render objects. @@ -1060,8 +1061,7 @@ class RenderEditor extends RenderEditableContainerBox // Don't change selection if the selected word is a placeholder. if (child.container.style.attributes - .containsKey(Attribute.placeholder.key) || child.container.style.attributes - .containsKey(Attribute.transparent.key)) { + .containsKey(Attribute.placeholder.key)) { return; } @@ -1087,6 +1087,9 @@ class RenderEditor extends RenderEditableContainerBox }) { final fromPosition = getPositionForOffset(from); final toPosition = to == null ? null : getPositionForOffset(to); + final child = childAtPosition(toPosition ?? fromPosition); + print(child as RenderEditableTextLine); + print(child.line); var baseOffset = fromPosition.offset; var extentOffset = fromPosition.offset; @@ -1448,6 +1451,7 @@ class RenderEditor extends RenderEditableContainerBox child.getCaretPrototype(child.globalToLocalPosition(textPosition)); _floatingCursorRect = sizeAdjustment.inflateRect(caretPrototype).shift(boundedOffset); + _cursorController .setFloatingCursorTextPosition(_floatingCursorTextPosition); } else { diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 6cdd6f6a0..87b58055b 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -25,6 +25,7 @@ import '../../document/nodes/block.dart'; import '../../document/nodes/embeddable.dart'; import '../../document/nodes/line.dart'; import '../../document/nodes/node.dart'; +import '../../document/style.dart'; import '../../editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; import '../editor.dart'; import '../widgets/cursor.dart'; diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 2e5dd9778..3ca9cb457 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -266,6 +266,9 @@ class _TextLineState extends State { ) { if (nodes.isEmpty && kIsWeb) { nodes = LinkedList()..add(leaf.QuillText('\u{200B}')); + } else if(nodes.isEmpty && widget.line.style.containsKey('header')){ + lineStyle = lineStyle.copyWith(color: defaultStyles.placeHolder?.style.color); + nodes = LinkedList()..add(leaf.QuillText('Header Placeholder')); } final children = nodes .map((node) => From d5e4f55537ae0bc2233fc4528681d7fcfa3a0dc4 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Tue, 17 Sep 2024 20:48:52 -0400 Subject: [PATCH 003/113] Feat: support for dynamic placeholders --- example/lib/screens/quill/quill_screen.dart | 20 ++++++ lib/flutter_quill.dart | 1 + lib/src/document/attribute.dart | 8 --- .../editor/config/editor_configurations.dart | 31 +++++++++ lib/src/editor/editor.dart | 7 +- .../placeholder_builder_internal.dart | 67 +++++++++++++++++++ .../placeholder_configuration.dart | 19 ++++++ .../config/raw_editor_configurations.dart | 6 ++ .../editor/raw_editor/raw_editor_state.dart | 3 +- lib/src/editor/widgets/text/text_block.dart | 4 ++ lib/src/editor/widgets/text/text_line.dart | 36 ++++++++-- 11 files changed, 185 insertions(+), 17 deletions(-) create mode 100644 lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart create mode 100644 lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index 97cb0abfe..b92fd9c91 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/quill/quill_screen.dart @@ -124,6 +124,26 @@ class _QuillScreenState extends State { child: MyQuillEditor( controller: _controller, configurations: QuillEditorConfigurations( + placeholderBuilder: { + Attribute.header.key: (Attribute attr, style) { + final values = [30, 27, 22]; + final level = attr.value as int?; + if (level == null) return null; + final fontSize = values[ + (level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; + return PlaceholderConfiguration( + placeholderText: 'Header $level', + style: TextStyle(fontSize: fontSize.toDouble()) + .merge(style.copyWith(color: Colors.grey)), + ); + }, + Attribute.list.key: (Attribute attr, style) { + return PlaceholderConfiguration( + placeholderText: 'List item', + style: style.copyWith(color: Colors.grey), + ); + }, + }, characterShortcutEvents: standardCharactersShortcutEvents, spaceShortcutEvents: standardSpaceShorcutEvents, searchConfigurations: const QuillSearchConfigurations( diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 868eed6ef..530222eaa 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -21,6 +21,7 @@ export 'src/editor/editor.dart'; export 'src/editor/embed/embed_editor_builder.dart'; export 'src/editor/provider.dart'; export 'src/editor/raw_editor/builders/leading_block_builder.dart'; +export 'src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart'; export 'src/editor/raw_editor/config/events/events.dart'; export 'src/editor/raw_editor/config/raw_editor_configurations.dart'; export 'src/editor/raw_editor/quill_single_child_scroll_view.dart'; diff --git a/lib/src/document/attribute.dart b/lib/src/document/attribute.dart index 8f021cb48..458bb9e22 100644 --- a/lib/src/document/attribute.dart +++ b/lib/src/document/attribute.dart @@ -88,8 +88,6 @@ class Attribute extends Equatable { static const BackgroundAttribute background = BackgroundAttribute(null); static const PlaceholderAttribute placeholder = PlaceholderAttribute(); - - static const TransparentAttribute transparent = TransparentAttribute(); static const HeaderAttribute header = HeaderAttribute(); @@ -354,12 +352,6 @@ class PlaceholderAttribute extends Attribute { : super('placeholder', AttributeScope.inline, true); } -/// This is custom attribute for hint -class TransparentAttribute extends Attribute { - const TransparentAttribute() - : super('transparent', AttributeScope.ignore, true); -} - class HeaderAttribute extends Attribute { const HeaderAttribute({int? level}) : super('header', AttributeScope.block, level); diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index 540f483c1..f43227320 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -12,6 +12,7 @@ import '../../toolbar/theme/quill_dialog_theme.dart'; import '../editor_builder.dart'; import '../embed/embed_editor_builder.dart'; import '../raw_editor/builders/leading_block_builder.dart'; +import '../raw_editor/builders/placeholder/placeholder_configuration.dart'; import '../raw_editor/config/events/events.dart'; import '../raw_editor/raw_editor.dart'; import '../widgets/default_styles.dart'; @@ -36,6 +37,7 @@ class QuillEditorConfigurations extends Equatable { this.padding = EdgeInsets.zero, this.characterShortcutEvents = const [], this.spaceShortcutEvents = const [], + this.placeholderBuilder = const {}, this.autoFocus = false, this.expands = false, this.placeholder, @@ -153,6 +155,33 @@ class QuillEditorConfigurations extends Equatable { ///``` final List spaceShortcutEvents; + /// Whether the line is empty, this let us add a placeholder + /// + /// _By now this is limited to the following block attributes:_ + /// _`header`, `list`, `code-block`, `blockquote`. Other attributes_ + /// _will be ignored_ + /// + /// ### Example + /// + /// Assume that you want to show only a placeholder text for the header items, + /// so, we only need to configure `placeholderBuilder` like: + /// + ///```dart + ///final defaultPlaceholderBuilder = { + /// Attribute.header.key: (Attribute attr, style) { + /// final values = [30, 27, 22]; + /// final level = attr.value as int?; + /// if (level == null) return null; + /// final fontSize = values[values[level - 1]]; + /// return PlaceholderConfiguration( + /// placeholderText: 'Header $level', + /// style: TextStyle(fontSize: fontSize.toDouble()).merge(style), + /// ); + /// }, + ///}, + ///``` + final Map placeholderBuilder; + /// Whether the text can be changed. /// /// When this is set to `true`, the text cannot be modified @@ -519,6 +548,7 @@ class QuillEditorConfigurations extends Equatable { GlobalKey? editorKey, TextSelectionThemeData? textSelectionThemeData, LeadingBlockNodeBuilder? customLeadingBlockBuilder, + Map? placeholderBuilder, bool? requestKeyboardFocusOnCheckListChanged, QuillEditorElementOptions? elementOptions, QuillEditorBuilder? builder, @@ -531,6 +561,7 @@ class QuillEditorConfigurations extends Equatable { }) { return QuillEditorConfigurations( sharedConfigurations: sharedConfigurations ?? this.sharedConfigurations, + placeholderBuilder: placeholderBuilder ?? this.placeholderBuilder, customLeadingBlockBuilder: customLeadingBlockBuilder ?? this.customLeadingBlockBuilder, // ignore: deprecated_member_use_from_same_package diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 093aa190f..f7aeedaa2 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -26,13 +26,13 @@ import 'config/editor_configurations.dart'; import 'editor_builder.dart'; import 'embed/embed_editor_builder.dart'; import 'provider.dart'; +import 'raw_editor/builders/placeholder/placeholder_builder_internal.dart'; import 'raw_editor/config/raw_editor_configurations.dart'; import 'raw_editor/raw_editor.dart'; import 'widgets/box.dart'; import 'widgets/cursor.dart'; import 'widgets/delegate.dart'; import 'widgets/float_cursor.dart'; -import 'widgets/text/text_line.dart'; import 'widgets/text/text_selection.dart'; /// Base interface for editable render objects. @@ -296,6 +296,8 @@ class QuillEditorState extends State key: _editorKey, controller: controller, configurations: QuillRawEditorConfigurations( + placeholderBuilder: PlaceholderBuilder( + builder: widget.configurations.placeholderBuilder), characterShortcutEvents: widget.configurations.characterShortcutEvents, spaceShortcutEvents: widget.configurations.spaceShortcutEvents, @@ -1087,9 +1089,6 @@ class RenderEditor extends RenderEditableContainerBox }) { final fromPosition = getPositionForOffset(from); final toPosition = to == null ? null : getPositionForOffset(to); - final child = childAtPosition(toPosition ?? fromPosition); - print(child as RenderEditableTextLine); - print(child.line); var baseOffset = fromPosition.offset; var extentOffset = fromPosition.offset; diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart new file mode 100644 index 000000000..94ce6c416 --- /dev/null +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -0,0 +1,67 @@ +// This file is only for internal use +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart' + show Expanded, Row, Text, TextDirection, TextStyle, TextWidthBasis, Widget; +import '../../../../document/attribute.dart' show Attribute; +import '../../../../document/nodes/line.dart'; +import 'placeholder_configuration.dart'; + +@immutable +class PlaceholderBuilder { + const PlaceholderBuilder({ + required this.builder, + }); + + final Map builder; + + /// Check if this node need to show a placeholder + (bool, String) shouldShowPlaceholder(Line node) { + if (builder.isEmpty) return (false, ''); + var shouldShow = false; + var key = ''; + // by now, we limit the available keys to show placeholder + // to 'header', 'list', 'code-block' and 'blockquote' + // + //TODO: we should take a look to let users add custom attributes + // keys to let them show placeholder on their own blocks + for (final exclusiveKey in Attribute.exclusiveBlockKeys) { + if (node.style.containsKey(exclusiveKey)) { + shouldShow = true; + key = exclusiveKey; + break; + } + } + // we return if should show placeholders and the key of the attr that matches to get it directly + // avoiding an unnecessary traverse into the attributes of the node + return (node.isEmpty && shouldShow, key); + } + + Widget? build({ + required Attribute blockAttribute, + required TextStyle lineStyle, + required TextDirection textDirection, + }) { + if (builder.isEmpty) return null; + final configuration = + builder[blockAttribute.key]?.call(blockAttribute, lineStyle); + // we return a row because this widget takes the whole width and makes possible + // select the block correctly (without this the block line cannot be selected correctly) + return configuration == null + ? null + : Row( + children: [ + // expanded let us add text as large as possible without breaks + // the horizontal view + Expanded( + child: Text( + configuration.placeholderText, + style: configuration.style, + textDirection: textDirection, + softWrap: true, + textWidthBasis: TextWidthBasis.longestLine, + ), + ), + ], + ); + } +} diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart new file mode 100644 index 000000000..21991fdb7 --- /dev/null +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart' show TextStyle, immutable; +import '../../../../document/attribute.dart'; + +typedef PlaceholderConfigurationBuilder = PlaceholderConfiguration? Function( + Attribute, TextStyle); + +@immutable + +/// Represents the configurations that builds how will +/// be displayed the placeholder text +class PlaceholderConfiguration { + const PlaceholderConfiguration({ + required this.placeholderText, + required this.style, + }); + + final String placeholderText; + final TextStyle style; +} diff --git a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart index 959bf2570..fc9368571 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart @@ -37,6 +37,7 @@ import '../../../editor/widgets/delegate.dart'; import '../../../editor/widgets/link.dart'; import '../../../toolbar/theme/quill_dialog_theme.dart'; import '../builders/leading_block_builder.dart'; +import '../builders/placeholder/placeholder_builder_internal.dart'; import 'events/events.dart'; @immutable @@ -52,6 +53,7 @@ class QuillRawEditorConfigurations extends Equatable { required this.autoFocus, required this.characterShortcutEvents, required this.spaceShortcutEvents, + required this.placeholderBuilder, @Deprecated( 'controller should be passed directly to the editor - this parameter will be removed in future versions.') this.controller, @@ -137,6 +139,10 @@ class QuillRawEditorConfigurations extends Equatable { ///``` final List characterShortcutEvents; + /// Contains all necessary logic to build the placeholder + /// given for the devs + final PlaceholderBuilder placeholderBuilder; + /// Contains all the events that will be handled when /// space key is pressed /// diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 87b58055b..875a1ab71 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -25,7 +25,6 @@ import '../../document/nodes/block.dart'; import '../../document/nodes/embeddable.dart'; import '../../document/nodes/line.dart'; import '../../document/nodes/node.dart'; -import '../../document/style.dart'; import '../../editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; import '../editor.dart'; import '../widgets/cursor.dart'; @@ -647,6 +646,7 @@ class QuillRawEditorState extends EditorState } else if (node is Block) { final editableTextBlock = EditableTextBlock( block: node, + placeholderBuilder: widget.configurations.placeholderBuilder, controller: controller, customLeadingBlockBuilder: widget.configurations.customLeadingBuilder, textDirection: nodeTextDirection, @@ -699,6 +699,7 @@ class QuillRawEditorState extends EditorState line: node, textDirection: _textDirection, embedBuilder: widget.configurations.embedBuilder, + placeholderBuilder: widget.configurations.placeholderBuilder, customStyleBuilder: widget.configurations.customStyleBuilder, customRecognizerBuilder: widget.configurations.customRecognizerBuilder, styles: _styles!, diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index 8208ab0f0..d24f00fcd 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -14,6 +14,7 @@ import '../../editor.dart'; import '../../embed/embed_editor_builder.dart'; import '../../provider.dart'; import '../../raw_editor/builders/leading_block_builder.dart'; +import '../../raw_editor/builders/placeholder/placeholder_builder_internal.dart'; import '../box.dart'; import '../cursor.dart'; import '../default_leading_components/leading_components.dart'; @@ -78,6 +79,7 @@ class EditableTextBlock extends StatelessWidget { required this.onCheckboxTap, required this.readOnly, required this.customRecognizerBuilder, + required this.placeholderBuilder, this.checkBoxReadOnly, this.onLaunchUrl, this.customStyleBuilder, @@ -92,6 +94,7 @@ class EditableTextBlock extends StatelessWidget { final double scrollBottomInset; final HorizontalSpacing horizontalSpacing; final VerticalSpacing verticalSpacing; + final PlaceholderBuilder placeholderBuilder; final TextSelection textSelection; final Color color; final DefaultStyles? styles; @@ -185,6 +188,7 @@ class EditableTextBlock extends StatelessWidget { line: line, textDirection: textDirection, embedBuilder: embedBuilder, + placeholderBuilder: placeholderBuilder, customStyleBuilder: customStyleBuilder, styles: styles!, readOnly: readOnly, diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 3ca9cb457..aacf78855 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -16,6 +16,7 @@ import '../../../common/utils/font.dart'; import '../../../common/utils/platform.dart'; import '../../../document/nodes/container.dart' as container_node; import '../../../document/nodes/leaf.dart' as leaf; +import '../../raw_editor/builders/placeholder/placeholder_builder_internal.dart'; import '../box.dart'; import '../delegate.dart'; import '../keyboard_listener.dart'; @@ -31,6 +32,7 @@ class TextLine extends StatefulWidget { required this.controller, required this.onLaunchUrl, required this.linkActionPicker, + required this.placeholderBuilder, this.textDirection, this.customStyleBuilder, this.customRecognizerBuilder, @@ -40,6 +42,7 @@ class TextLine extends StatefulWidget { final Line line; final TextDirection? textDirection; + final PlaceholderBuilder placeholderBuilder; final EmbedsBuilder embedBuilder; final DefaultStyles styles; final bool readOnly; @@ -266,9 +269,27 @@ class _TextLineState extends State { ) { if (nodes.isEmpty && kIsWeb) { nodes = LinkedList()..add(leaf.QuillText('\u{200B}')); - } else if(nodes.isEmpty && widget.line.style.containsKey('header')){ - lineStyle = lineStyle.copyWith(color: defaultStyles.placeHolder?.style.color); - nodes = LinkedList()..add(leaf.QuillText('Header Placeholder')); + } else if (nodes.isEmpty) { + final (shouldShowNode, attrKey) = + widget.placeholderBuilder.shouldShowPlaceholder(widget.line); + if (shouldShowNode) { + final style = _getInlineTextStyle( + const Style(), defaultStyles, widget.line.style, false); + final placeholderWidget = widget.placeholderBuilder.build( + blockAttribute: widget.line.style.attributes[attrKey]!, + lineStyle: lineStyle.merge(style), + textDirection: widget.textDirection ?? Directionality.of(context), + ); + if (placeholderWidget != null) { + final widgetSpan = _getTextSpanFromNode( + defaultStyles, + leaf.QuillText(), + widget.line.style, + placeholderWidget: placeholderWidget, + ); + return TextSpan(children: [widgetSpan], style: lineStyle); + } + } } final children = nodes .map((node) => @@ -404,7 +425,11 @@ class _TextLineState extends State { } InlineSpan _getTextSpanFromNode( - DefaultStyles defaultStyles, Node node, Style lineStyle) { + DefaultStyles defaultStyles, + Node node, + Style lineStyle, { + Widget? placeholderWidget, + }) { final textNode = node as leaf.QuillText; final nodeStyle = textNode.style; final isLink = nodeStyle.containsKey(Attribute.link.key) && @@ -421,6 +446,9 @@ class _TextLineState extends State { } } } + if (!isLink && placeholderWidget != null) { + return WidgetSpan(child: placeholderWidget); + } if (!isLink && !widget.readOnly && From 8f4b0da05d2b4cce503dbe4a2cb503763716f41c Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Tue, 17 Sep 2024 21:30:20 -0400 Subject: [PATCH 004/113] Fix: web cannot use dynamic placeholders --- lib/src/editor/widgets/text/text_line.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index aacf78855..60fa12d69 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -267,9 +267,8 @@ class _TextLineState extends State { LinkedList nodes, TextStyle lineStyle, ) { - if (nodes.isEmpty && kIsWeb) { - nodes = LinkedList()..add(leaf.QuillText('\u{200B}')); - } else if (nodes.isEmpty) { + var addWebNodeIfNeeded = false; + if (nodes.isEmpty && widget.placeholderBuilder.builder.isNotEmpty) { final (shouldShowNode, attrKey) = widget.placeholderBuilder.shouldShowPlaceholder(widget.line); if (shouldShowNode) { @@ -290,6 +289,13 @@ class _TextLineState extends State { return TextSpan(children: [widgetSpan], style: lineStyle); } } + // if the [placeholderWidget] is null or shouldShowNode is false + // then this line will be executed and avoid non add + // the needed node when the line is empty + addWebNodeIfNeeded = true; + } + if (nodes.isEmpty && kIsWeb && addWebNodeIfNeeded) { + nodes = LinkedList()..add(leaf.QuillText('\u{200B}')); } final children = nodes .map((node) => From 14fe2b3462c3cdb6fc243887f12dbef16c2eff05 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Tue, 17 Sep 2024 21:42:04 -0400 Subject: [PATCH 005/113] Chore: removed isLink check since is unnecessary --- lib/src/editor/widgets/text/text_line.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 60fa12d69..de110be8d 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -289,7 +289,7 @@ class _TextLineState extends State { return TextSpan(children: [widgetSpan], style: lineStyle); } } - // if the [placeholderWidget] is null or shouldShowNode is false + // if the [placeholderWidget] is null or [shouldShowNode] is false // then this line will be executed and avoid non add // the needed node when the line is empty addWebNodeIfNeeded = true; @@ -452,7 +452,7 @@ class _TextLineState extends State { } } } - if (!isLink && placeholderWidget != null) { + if (placeholderWidget != null) { return WidgetSpan(child: placeholderWidget); } From 811c9a0034f6f41e4723393c0c5192c628eb7f1e Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Tue, 17 Sep 2024 21:43:44 -0400 Subject: [PATCH 006/113] Chore: renamed builder param to builders for make more sense to its functionality --- lib/src/editor/editor.dart | 2 +- .../placeholder/placeholder_builder_internal.dart | 10 +++++----- lib/src/editor/widgets/text/text_line.dart | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index f7aeedaa2..1ec346f0b 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -297,7 +297,7 @@ class QuillEditorState extends State controller: controller, configurations: QuillRawEditorConfigurations( placeholderBuilder: PlaceholderBuilder( - builder: widget.configurations.placeholderBuilder), + builders: widget.configurations.placeholderBuilder), characterShortcutEvents: widget.configurations.characterShortcutEvents, spaceShortcutEvents: widget.configurations.spaceShortcutEvents, diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 94ce6c416..cfabf522a 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -9,14 +9,14 @@ import 'placeholder_configuration.dart'; @immutable class PlaceholderBuilder { const PlaceholderBuilder({ - required this.builder, + required this.builders, }); - final Map builder; + final Map builders; /// Check if this node need to show a placeholder (bool, String) shouldShowPlaceholder(Line node) { - if (builder.isEmpty) return (false, ''); + if (builders.isEmpty) return (false, ''); var shouldShow = false; var key = ''; // by now, we limit the available keys to show placeholder @@ -41,9 +41,9 @@ class PlaceholderBuilder { required TextStyle lineStyle, required TextDirection textDirection, }) { - if (builder.isEmpty) return null; + if (builders.isEmpty) return null; final configuration = - builder[blockAttribute.key]?.call(blockAttribute, lineStyle); + builders[blockAttribute.key]?.call(blockAttribute, lineStyle); // we return a row because this widget takes the whole width and makes possible // select the block correctly (without this the block line cannot be selected correctly) return configuration == null diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index de110be8d..521cd7d89 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -268,7 +268,7 @@ class _TextLineState extends State { TextStyle lineStyle, ) { var addWebNodeIfNeeded = false; - if (nodes.isEmpty && widget.placeholderBuilder.builder.isNotEmpty) { + if (nodes.isEmpty && widget.placeholderBuilder.builders.isNotEmpty) { final (shouldShowNode, attrKey) = widget.placeholderBuilder.shouldShowPlaceholder(widget.line); if (shouldShowNode) { From c9c5a3df4438a6c8299a4580639a7ca6cd9b66ab Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Tue, 17 Sep 2024 21:55:19 -0400 Subject: [PATCH 007/113] Chore: dart format . --- lib/src/editor/widgets/text/text_line.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 521cd7d89..b30be7fff 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -290,10 +290,10 @@ class _TextLineState extends State { } } // if the [placeholderWidget] is null or [shouldShowNode] is false - // then this line will be executed and avoid non add + // then this line will be executed and avoid non add // the needed node when the line is empty addWebNodeIfNeeded = true; - } + } if (nodes.isEmpty && kIsWeb && addWebNodeIfNeeded) { nodes = LinkedList()..add(leaf.QuillText('\u{200B}')); } From 98f817fdc40fd9431b3ed23c2a78cfaea5e3f165 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Tue, 17 Sep 2024 21:55:42 -0400 Subject: [PATCH 008/113] Chore: fix example in doc comment --- lib/src/editor/config/editor_configurations.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index f43227320..ab210496e 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -172,7 +172,7 @@ class QuillEditorConfigurations extends Equatable { /// final values = [30, 27, 22]; /// final level = attr.value as int?; /// if (level == null) return null; - /// final fontSize = values[values[level - 1]]; + /// final fontSize = values[level - 1]; /// return PlaceholderConfiguration( /// placeholderText: 'Header $level', /// style: TextStyle(fontSize: fontSize.toDouble()).merge(style), From d2a0a63799f38ded873163bd906e333bdc33b5b6 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Tue, 17 Sep 2024 22:03:37 -0400 Subject: [PATCH 009/113] Chore: renamed PlaceholderConfiguration to PlaceholderArguments --- example/lib/screens/quill/quill_screen.dart | 4 ++-- lib/src/editor/config/editor_configurations.dart | 2 +- .../placeholder/placeholder_configuration.dart | 11 +++++------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index b92fd9c91..5543cf1bc 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/quill/quill_screen.dart @@ -131,14 +131,14 @@ class _QuillScreenState extends State { if (level == null) return null; final fontSize = values[ (level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; - return PlaceholderConfiguration( + return PlaceholderArguments( placeholderText: 'Header $level', style: TextStyle(fontSize: fontSize.toDouble()) .merge(style.copyWith(color: Colors.grey)), ); }, Attribute.list.key: (Attribute attr, style) { - return PlaceholderConfiguration( + return PlaceholderArguments( placeholderText: 'List item', style: style.copyWith(color: Colors.grey), ); diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index ab210496e..ae68fc4e8 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -173,7 +173,7 @@ class QuillEditorConfigurations extends Equatable { /// final level = attr.value as int?; /// if (level == null) return null; /// final fontSize = values[level - 1]; - /// return PlaceholderConfiguration( + /// return PlaceholderArguments( /// placeholderText: 'Header $level', /// style: TextStyle(fontSize: fontSize.toDouble()).merge(style), /// ); diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart index 21991fdb7..4ee3e6d24 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart @@ -1,15 +1,14 @@ import 'package:flutter/material.dart' show TextStyle, immutable; import '../../../../document/attribute.dart'; -typedef PlaceholderConfigurationBuilder = PlaceholderConfiguration? Function( +typedef PlaceholderConfigurationBuilder = PlaceholderArguments? Function( Attribute, TextStyle); @immutable - -/// Represents the configurations that builds how will -/// be displayed the placeholder text -class PlaceholderConfiguration { - const PlaceholderConfiguration({ +/// Represents the arguments that builds the text that will +/// be displayed +class PlaceholderArguments { + const PlaceholderArguments({ required this.placeholderText, required this.style, }); From dd81cc2f7c49e469a6d0fd504091f2cb61debc5f Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Wed, 18 Sep 2024 01:39:34 -0400 Subject: [PATCH 010/113] Feat: support custom attributes for placeholders --- example/lib/screens/quill/quill_screen.dart | 41 ++++++++-------- .../editor/config/editor_configurations.dart | 25 +++++----- lib/src/editor/editor.dart | 4 +- .../placeholder_builder_internal.dart | 47 ++++++++++++++----- .../placeholder_configuration.dart | 29 ++++++++++++ 5 files changed, 103 insertions(+), 43 deletions(-) diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index 5543cf1bc..8c794737f 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/quill/quill_screen.dart @@ -124,26 +124,29 @@ class _QuillScreenState extends State { child: MyQuillEditor( controller: _controller, configurations: QuillEditorConfigurations( - placeholderBuilder: { - Attribute.header.key: (Attribute attr, style) { - final values = [30, 27, 22]; - final level = attr.value as int?; - if (level == null) return null; - final fontSize = values[ - (level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; - return PlaceholderArguments( - placeholderText: 'Header $level', - style: TextStyle(fontSize: fontSize.toDouble()) - .merge(style.copyWith(color: Colors.grey)), - ); + placeholderComponentsConfiguration: + PlaceholderComponentsConfiguration( + builders: { + Attribute.header.key: (Attribute attr, style) { + final values = [30, 27, 22]; + final level = attr.value as int?; + if (level == null) return null; + final fontSize = values[ + (level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; + return PlaceholderArguments( + placeholderText: 'Header $level', + style: TextStyle(fontSize: fontSize.toDouble()) + .merge(style.copyWith(color: Colors.grey)), + ); + }, + Attribute.list.key: (Attribute attr, style) { + return PlaceholderArguments( + placeholderText: 'List item', + style: style.copyWith(color: Colors.grey), + ); + }, }, - Attribute.list.key: (Attribute attr, style) { - return PlaceholderArguments( - placeholderText: 'List item', - style: style.copyWith(color: Colors.grey), - ); - }, - }, + ), characterShortcutEvents: standardCharactersShortcutEvents, spaceShortcutEvents: standardSpaceShorcutEvents, searchConfigurations: const QuillSearchConfigurations( diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index ae68fc4e8..0efec2e2e 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -37,7 +37,8 @@ class QuillEditorConfigurations extends Equatable { this.padding = EdgeInsets.zero, this.characterShortcutEvents = const [], this.spaceShortcutEvents = const [], - this.placeholderBuilder = const {}, + this.placeholderComponentsConfiguration = + const PlaceholderComponentsConfiguration(builders: {}), this.autoFocus = false, this.expands = false, this.placeholder, @@ -157,17 +158,14 @@ class QuillEditorConfigurations extends Equatable { /// Whether the line is empty, this let us add a placeholder /// - /// _By now this is limited to the following block attributes:_ - /// _`header`, `list`, `code-block`, `blockquote`. Other attributes_ - /// _will be ignored_ - /// /// ### Example /// /// Assume that you want to show only a placeholder text for the header items, - /// so, we only need to configure `placeholderBuilder` like: + /// so, we only need to configure `placeholderComponentsConfiguration` like: /// ///```dart - ///final defaultPlaceholderBuilder = { + ///final configuration = PlaceholderComponentsConfiguration( + /// builders: { /// Attribute.header.key: (Attribute attr, style) { /// final values = [30, 27, 22]; /// final level = attr.value as int?; @@ -178,9 +176,13 @@ class QuillEditorConfigurations extends Equatable { /// style: TextStyle(fontSize: fontSize.toDouble()).merge(style), /// ); /// }, - ///}, + /// }, + /// // if you use custom attribute keys into the `builders` param, them you will need to implement that + /// // here too + /// customBlockAttributesKeys: null, + ///), ///``` - final Map placeholderBuilder; + final PlaceholderComponentsConfiguration placeholderComponentsConfiguration; /// Whether the text can be changed. /// @@ -548,7 +550,7 @@ class QuillEditorConfigurations extends Equatable { GlobalKey? editorKey, TextSelectionThemeData? textSelectionThemeData, LeadingBlockNodeBuilder? customLeadingBlockBuilder, - Map? placeholderBuilder, + PlaceholderComponentsConfiguration? placeholderComponentsConfiguration, bool? requestKeyboardFocusOnCheckListChanged, QuillEditorElementOptions? elementOptions, QuillEditorBuilder? builder, @@ -561,7 +563,8 @@ class QuillEditorConfigurations extends Equatable { }) { return QuillEditorConfigurations( sharedConfigurations: sharedConfigurations ?? this.sharedConfigurations, - placeholderBuilder: placeholderBuilder ?? this.placeholderBuilder, + placeholderComponentsConfiguration: placeholderComponentsConfiguration ?? + this.placeholderComponentsConfiguration, customLeadingBlockBuilder: customLeadingBlockBuilder ?? this.customLeadingBlockBuilder, // ignore: deprecated_member_use_from_same_package diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 1ec346f0b..f9dbfb5d2 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -297,7 +297,9 @@ class QuillEditorState extends State controller: controller, configurations: QuillRawEditorConfigurations( placeholderBuilder: PlaceholderBuilder( - builders: widget.configurations.placeholderBuilder), + configuration: + widget.configurations.placeholderComponentsConfiguration, + ), characterShortcutEvents: widget.configurations.characterShortcutEvents, spaceShortcutEvents: widget.configurations.spaceShortcutEvents, diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index cfabf522a..a6797c1a4 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -1,31 +1,54 @@ // This file is only for internal use -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart' - show Expanded, Row, Text, TextDirection, TextStyle, TextWidthBasis, Widget; -import '../../../../document/attribute.dart' show Attribute; + show + Expanded, + Row, + Text, + TextDirection, + TextStyle, + TextWidthBasis, + Widget, + immutable; +import '../../../../document/attribute.dart' show Attribute, AttributeScope; import '../../../../document/nodes/line.dart'; import 'placeholder_configuration.dart'; +/// This is the black list of the keys that cannot be +/// used or permitted by the builder +final List _blackList = List.unmodifiable([ + Attribute.align.key, + Attribute.direction.key, + Attribute.lineHeight.key, + Attribute.indent.key, + ...Attribute.inlineKeys, + ...Attribute.ignoreKeys, +]); + @immutable class PlaceholderBuilder { const PlaceholderBuilder({ - required this.builders, + required this.configuration, }); - final Map builders; + final PlaceholderComponentsConfiguration configuration; + + Map get builders => + configuration.builders; + Set? get customBlockAttributesKeys => + configuration.customBlockAttributesKeys; /// Check if this node need to show a placeholder (bool, String) shouldShowPlaceholder(Line node) { if (builders.isEmpty) return (false, ''); var shouldShow = false; var key = ''; - // by now, we limit the available keys to show placeholder - // to 'header', 'list', 'code-block' and 'blockquote' - // - //TODO: we should take a look to let users add custom attributes - // keys to let them show placeholder on their own blocks - for (final exclusiveKey in Attribute.exclusiveBlockKeys) { - if (node.style.containsKey(exclusiveKey)) { + for (final exclusiveKey in { + ...Attribute.exclusiveBlockKeys, + ...?customBlockAttributesKeys + }) { + if (node.style.containsKey(exclusiveKey) && + node.style.attributes[exclusiveKey]?.scope == AttributeScope.block && + !_blackList.contains(exclusiveKey)) { shouldShow = true; key = exclusiveKey; break; diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart index 4ee3e6d24..5a0f1c77a 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart @@ -5,6 +5,35 @@ typedef PlaceholderConfigurationBuilder = PlaceholderArguments? Function( Attribute, TextStyle); @immutable +class PlaceholderComponentsConfiguration { + const PlaceholderComponentsConfiguration({ + required this.builders, + this.customBlockAttributesKeys, + }); + + factory PlaceholderComponentsConfiguration.base() { + return const PlaceholderComponentsConfiguration(builders: {}); + } + + /// These attributes are used with the default ones + /// to let us add placeholder to custom block attributes + final Set? customBlockAttributesKeys; + final Map builders; + + PlaceholderComponentsConfiguration copyWith({ + Map? builders, + Set? customBlockAttributesKeys, + }) { + return PlaceholderComponentsConfiguration( + builders: builders ?? this.builders, + customBlockAttributesKeys: + customBlockAttributesKeys ?? this.customBlockAttributesKeys, + ); + } +} + +@immutable + /// Represents the arguments that builds the text that will /// be displayed class PlaceholderArguments { From 82b3780f78bdf81f32c31743b4558b94c45a3158 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Wed, 18 Sep 2024 01:45:00 -0400 Subject: [PATCH 011/113] Chore: dart format --- .../builders/placeholder/placeholder_builder_internal.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index a6797c1a4..719cfa693 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -13,7 +13,7 @@ import '../../../../document/attribute.dart' show Attribute, AttributeScope; import '../../../../document/nodes/line.dart'; import 'placeholder_configuration.dart'; -/// This is the black list of the keys that cannot be +/// This is the black list of the keys that cannot be /// used or permitted by the builder final List _blackList = List.unmodifiable([ Attribute.align.key, @@ -47,7 +47,7 @@ class PlaceholderBuilder { ...?customBlockAttributesKeys }) { if (node.style.containsKey(exclusiveKey) && - node.style.attributes[exclusiveKey]?.scope == AttributeScope.block && + node.style.attributes[exclusiveKey]?.scope == AttributeScope.block && !_blackList.contains(exclusiveKey)) { shouldShow = true; key = exclusiveKey; From 5741e6b71fc87dfad82c36ff95add5853187916a Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Wed, 18 Sep 2024 01:49:36 -0400 Subject: [PATCH 012/113] Chore: added late keyword for blackList --- .../builders/placeholder/placeholder_builder_internal.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 719cfa693..7076cc47f 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -15,7 +15,8 @@ import 'placeholder_configuration.dart'; /// This is the black list of the keys that cannot be /// used or permitted by the builder -final List _blackList = List.unmodifiable([ +// ignore: unnecessary_late +late final List _blackList = List.unmodifiable([ Attribute.align.key, Attribute.direction.key, Attribute.lineHeight.key, From d6edcd2ffb88f13472d37a62abe27b4996a5ad1c Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Wed, 18 Sep 2024 03:21:50 -0400 Subject: [PATCH 013/113] Feat: added support for cursor placeholder --- example/lib/screens/quill/quill_screen.dart | 3 ++ lib/flutter_quill.dart | 1 + .../editor/config/editor_configurations.dart | 13 +++++ lib/src/editor/editor.dart | 2 + .../config/raw_editor_configurations.dart | 6 +++ .../editor/raw_editor/raw_editor_state.dart | 5 +- lib/src/editor/widgets/cursor.dart | 31 +++++++++++ .../cursor_configuration.dart | 52 +++++++++++++++++++ lib/src/editor/widgets/text/text_block.dart | 5 ++ lib/src/editor/widgets/text/text_line.dart | 22 +++++++- 10 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index 8c794737f..f0bfcd976 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/quill/quill_screen.dart @@ -124,6 +124,9 @@ class _QuillScreenState extends State { child: MyQuillEditor( controller: _controller, configurations: QuillEditorConfigurations( + cursorParagrahPlaceholderConfiguration: + CursorParagrahPlaceholderConfiguration + .withPlaceholder(), placeholderComponentsConfiguration: PlaceholderComponentsConfiguration( builders: { diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 530222eaa..d2adcfc4b 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -31,6 +31,7 @@ export 'src/editor/spellchecker/spellchecker_service.dart'; export 'src/editor/spellchecker/spellchecker_service_provider.dart'; export 'src/editor/style_widgets/style_widgets.dart'; export 'src/editor/widgets/cursor.dart'; +export 'src/editor/widgets/cursor_configuration/cursor_configuration.dart'; export 'src/editor/widgets/default_styles.dart'; export 'src/editor/widgets/link.dart'; export 'src/editor/widgets/text/utils/text_block_utils.dart'; diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index 0efec2e2e..6836f2d0f 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -15,6 +15,7 @@ import '../raw_editor/builders/leading_block_builder.dart'; import '../raw_editor/builders/placeholder/placeholder_configuration.dart'; import '../raw_editor/config/events/events.dart'; import '../raw_editor/raw_editor.dart'; +import '../widgets/cursor_configuration/cursor_configuration.dart'; import '../widgets/default_styles.dart'; import '../widgets/delegate.dart'; import '../widgets/link.dart'; @@ -39,6 +40,9 @@ class QuillEditorConfigurations extends Equatable { this.spaceShortcutEvents = const [], this.placeholderComponentsConfiguration = const PlaceholderComponentsConfiguration(builders: {}), + this.cursorParagrahPlaceholderConfiguration = + const CursorParagrahPlaceholderConfiguration( + paragraphPlaceholderText: '', style: TextStyle(), show: false), this.autoFocus = false, this.expands = false, this.placeholder, @@ -184,6 +188,10 @@ class QuillEditorConfigurations extends Equatable { ///``` final PlaceholderComponentsConfiguration placeholderComponentsConfiguration; + /// This argument configure how will be showed the placeholder at right or left of the cursor + final CursorParagrahPlaceholderConfiguration + cursorParagrahPlaceholderConfiguration; + /// Whether the text can be changed. /// /// When this is set to `true`, the text cannot be modified @@ -554,6 +562,8 @@ class QuillEditorConfigurations extends Equatable { bool? requestKeyboardFocusOnCheckListChanged, QuillEditorElementOptions? elementOptions, QuillEditorBuilder? builder, + CursorParagrahPlaceholderConfiguration? + cursorParagrahPlaceholderConfiguration, TextMagnifierConfiguration? magnifierConfiguration, TextInputAction? textInputAction, bool? enableScribble, @@ -563,6 +573,9 @@ class QuillEditorConfigurations extends Equatable { }) { return QuillEditorConfigurations( sharedConfigurations: sharedConfigurations ?? this.sharedConfigurations, + cursorParagrahPlaceholderConfiguration: + cursorParagrahPlaceholderConfiguration ?? + this.cursorParagrahPlaceholderConfiguration, placeholderComponentsConfiguration: placeholderComponentsConfiguration ?? this.placeholderComponentsConfiguration, customLeadingBlockBuilder: diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index f9dbfb5d2..82cf8cda9 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -296,6 +296,8 @@ class QuillEditorState extends State key: _editorKey, controller: controller, configurations: QuillRawEditorConfigurations( + cursorParagrahPlaceholderConfiguration: + widget.configurations.cursorParagrahPlaceholderConfiguration, placeholderBuilder: PlaceholderBuilder( configuration: widget.configurations.placeholderComponentsConfiguration, diff --git a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart index fc9368571..9fec017ca 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart @@ -36,6 +36,7 @@ import '../../../editor/widgets/default_styles.dart'; import '../../../editor/widgets/delegate.dart'; import '../../../editor/widgets/link.dart'; import '../../../toolbar/theme/quill_dialog_theme.dart'; +import '../../widgets/cursor_configuration/cursor_configuration.dart'; import '../builders/leading_block_builder.dart'; import '../builders/placeholder/placeholder_builder_internal.dart'; import 'events/events.dart'; @@ -56,6 +57,7 @@ class QuillRawEditorConfigurations extends Equatable { required this.placeholderBuilder, @Deprecated( 'controller should be passed directly to the editor - this parameter will be removed in future versions.') + required this.cursorParagrahPlaceholderConfiguration, this.controller, this.showCursor = true, this.scrollable = true, @@ -165,6 +167,10 @@ class QuillRawEditorConfigurations extends Equatable { ///``` final List spaceShortcutEvents; + /// This argument configure how will be showed the placeholder at right or left of the cursor + final CursorParagrahPlaceholderConfiguration + cursorParagrahPlaceholderConfiguration; + /// Additional space around the editor contents. final EdgeInsetsGeometry padding; diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 875a1ab71..04a913691 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -648,6 +648,8 @@ class QuillRawEditorState extends EditorState block: node, placeholderBuilder: widget.configurations.placeholderBuilder, controller: controller, + cursorParagrahPlaceholderConfiguration: + widget.configurations.cursorParagrahPlaceholderConfiguration, customLeadingBlockBuilder: widget.configurations.customLeadingBuilder, textDirection: nodeTextDirection, scrollBottomInset: widget.configurations.scrollBottomInset, @@ -722,7 +724,8 @@ class QuillRawEditorState extends EditorState _hasFocus, MediaQuery.devicePixelRatioOf(context), _cursorCont, - _styles!.inlineCode!); + _styles!.inlineCode!, + widget.configurations.cursorParagrahPlaceholderConfiguration); return editableTextLine; } diff --git a/lib/src/editor/widgets/cursor.dart b/lib/src/editor/widgets/cursor.dart index e89df9e81..29929510d 100644 --- a/lib/src/editor/widgets/cursor.dart +++ b/lib/src/editor/widgets/cursor.dart @@ -3,7 +3,9 @@ import 'dart:async'; import 'package:flutter/widgets.dart'; import '../../common/utils/platform.dart'; +import '../../document/nodes/line.dart'; import 'box.dart'; +import 'cursor_configuration/cursor_configuration.dart'; /// Style properties of editing cursor. class CursorStyle { @@ -252,6 +254,7 @@ class CursorPainter { final Rect prototype; final Color color; final double devicePixelRatio; + TextPainter? placeholderPainter; /// Paints cursor on [canvas] at specified [position]. /// [offset] is global top left (x, y) of text line @@ -261,6 +264,9 @@ class CursorPainter { Offset offset, TextPosition position, bool lineHasEmbed, + Line node, + CursorParagrahPlaceholderConfiguration cursorPlaceholderConfiguration, + TextDirection textDirection, ) { // relative (x, y) to global offset var relativeCaretOffset = editable!.getOffsetForCaret(position, prototype); @@ -325,6 +331,31 @@ class CursorPainter { final caretRRect = RRect.fromRectAndRadius(caretRect, style.radius!); canvas.drawRRect(caretRRect, paint); } + // we need to make these checks to avoid use this painter unnecessarily + if (cursorPlaceholderConfiguration.show && + cursorPlaceholderConfiguration.paragraphPlaceholderText + .trim() + .isNotEmpty) { + if (_isNodeInline(node) && node.isEmpty) { + placeholderPainter ??= TextPainter( + text: TextSpan( + text: cursorPlaceholderConfiguration.paragraphPlaceholderText, + style: cursorPlaceholderConfiguration.style, + ), + textDirection: textDirection, + ); + placeholderPainter! + ..layout() + ..paint(canvas, offset + Offset(3.5, (style.height ?? 2) / 2)); + } + } + } + + bool _isNodeInline(Line node) { + for (final attr in node.style.attributes.values) { + if (!attr.isInline) return false; + } + return true; } Offset _getPixelPerfectCursorOffset( diff --git a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart new file mode 100644 index 000000000..5d89863fb --- /dev/null +++ b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart @@ -0,0 +1,52 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; + +/// This class contains all necessary configurations +/// to show the wanted placeholder at the level of the cursor +/// +/// You can see this as some Rich Text Editors can contains a feature +/// where if the line is empty and not contains any block style (like +/// header, align, codeblock, etc), then will show a text +/// like (assume that "|" is the cursor): "| start writing" + +const TextStyle _defaultPlaceholderStyle = + TextStyle(color: Colors.grey, fontStyle: FontStyle.italic); + +@immutable +class CursorParagrahPlaceholderConfiguration extends Equatable { + const CursorParagrahPlaceholderConfiguration({ + required this.paragraphPlaceholderText, + required this.style, + required this.show, + }); + + factory CursorParagrahPlaceholderConfiguration.withPlaceholder( + {TextStyle? style}) { + return CursorParagrahPlaceholderConfiguration( + paragraphPlaceholderText: 'Enter text...', + style: style ?? _defaultPlaceholderStyle, + show: true, + ); + } + + factory CursorParagrahPlaceholderConfiguration.noPlaceholder() { + return const CursorParagrahPlaceholderConfiguration( + paragraphPlaceholderText: '', + style: TextStyle(), + show: false, + ); + } + + /// The text that will be showed at the right + /// or left of the cursor + final String paragraphPlaceholderText; + + /// The style of the placeholder + final TextStyle style; + + /// Decides if the placeholder should be showed + final bool show; + + @override + List get props => [paragraphPlaceholderText, style, show]; +} diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index d24f00fcd..a4fa00060 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -17,6 +17,7 @@ import '../../raw_editor/builders/leading_block_builder.dart'; import '../../raw_editor/builders/placeholder/placeholder_builder_internal.dart'; import '../box.dart'; import '../cursor.dart'; +import '../cursor_configuration/cursor_configuration.dart'; import '../default_leading_components/leading_components.dart'; import '../default_styles.dart'; import '../delegate.dart'; @@ -80,6 +81,7 @@ class EditableTextBlock extends StatelessWidget { required this.readOnly, required this.customRecognizerBuilder, required this.placeholderBuilder, + required this.cursorParagrahPlaceholderConfiguration, this.checkBoxReadOnly, this.onLaunchUrl, this.customStyleBuilder, @@ -95,6 +97,8 @@ class EditableTextBlock extends StatelessWidget { final HorizontalSpacing horizontalSpacing; final VerticalSpacing verticalSpacing; final PlaceholderBuilder placeholderBuilder; + final CursorParagrahPlaceholderConfiguration + cursorParagrahPlaceholderConfiguration; final TextSelection textSelection; final Color color; final DefaultStyles? styles; @@ -208,6 +212,7 @@ class EditableTextBlock extends StatelessWidget { MediaQuery.devicePixelRatioOf(context), cursorCont, styles!.inlineCode!, + cursorParagrahPlaceholderConfiguration, ); final nodeTextDirection = getDirectionOfNode(line, textDirection); children.add( diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index b30be7fff..35390cbcf 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -680,6 +680,7 @@ class EditableTextLine extends RenderObjectWidget { this.devicePixelRatio, this.cursorCont, this.inlineCodeStyle, + this.cursorParagrahPlaceholderConfiguration, {super.key}); final Line line; @@ -687,6 +688,8 @@ class EditableTextLine extends RenderObjectWidget { final Widget body; final HorizontalSpacing horizontalSpacing; final VerticalSpacing verticalSpacing; + final CursorParagrahPlaceholderConfiguration + cursorParagrahPlaceholderConfiguration; final TextDirection textDirection; final TextSelection textSelection; final Color color; @@ -713,7 +716,8 @@ class EditableTextLine extends RenderObjectWidget { _getPadding(), color, cursorCont, - inlineCodeStyle); + inlineCodeStyle, + cursorParagrahPlaceholderConfiguration); } @override @@ -725,6 +729,8 @@ class EditableTextLine extends RenderObjectWidget { ..setTextDirection(textDirection) ..setTextSelection(textSelection) ..setColor(color) + ..setCursorParagraphPlaceholderConfiguration( + cursorParagrahPlaceholderConfiguration) ..setEnableInteractiveSelection(enableInteractiveSelection) ..hasFocus = hasFocus ..setDevicePixelRatio(devicePixelRatio) @@ -756,6 +762,7 @@ class RenderEditableTextLine extends RenderEditableBox { this.color, this.cursorCont, this.inlineCodeStyle, + this.cursorParagrahPlaceholderConfiguration, ); RenderBox? _leading; @@ -765,6 +772,7 @@ class RenderEditableTextLine extends RenderEditableBox { TextSelection textSelection; Color color; bool enableInteractiveSelection; + CursorParagrahPlaceholderConfiguration cursorParagrahPlaceholderConfiguration; bool hasFocus = false; double devicePixelRatio; EdgeInsetsGeometry padding; @@ -793,6 +801,15 @@ class RenderEditableTextLine extends RenderEditableBox { markNeedsLayout(); } + void setCursorParagraphPlaceholderConfiguration( + CursorParagrahPlaceholderConfiguration c) { + if (cursorParagrahPlaceholderConfiguration == c) { + return; + } + cursorParagrahPlaceholderConfiguration = c; + markNeedsLayout(); + } + void setDevicePixelRatio(double d) { if (devicePixelRatio == d) { return; @@ -1399,6 +1416,9 @@ class RenderEditableTextLine extends RenderEditableBox { effectiveOffset, position, lineHasEmbed, + line, + cursorParagrahPlaceholderConfiguration, + textDirection, ); } From 8d274a0be7fb647fe7b392313fc7ae8d78769939 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Wed, 18 Sep 2024 03:36:59 -0400 Subject: [PATCH 014/113] Fix: make CursorParagraphPlaceholderConfiguration nullable --- lib/src/editor/config/editor_configurations.dart | 6 ++---- .../editor/raw_editor/config/raw_editor_configurations.dart | 4 ++-- lib/src/editor/widgets/cursor.dart | 4 ++-- lib/src/editor/widgets/text/text_block.dart | 2 +- lib/src/editor/widgets/text/text_line.dart | 6 +++--- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index 6836f2d0f..7349a9782 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -40,9 +40,7 @@ class QuillEditorConfigurations extends Equatable { this.spaceShortcutEvents = const [], this.placeholderComponentsConfiguration = const PlaceholderComponentsConfiguration(builders: {}), - this.cursorParagrahPlaceholderConfiguration = - const CursorParagrahPlaceholderConfiguration( - paragraphPlaceholderText: '', style: TextStyle(), show: false), + this.cursorParagrahPlaceholderConfiguration, this.autoFocus = false, this.expands = false, this.placeholder, @@ -189,7 +187,7 @@ class QuillEditorConfigurations extends Equatable { final PlaceholderComponentsConfiguration placeholderComponentsConfiguration; /// This argument configure how will be showed the placeholder at right or left of the cursor - final CursorParagrahPlaceholderConfiguration + final CursorParagrahPlaceholderConfiguration? cursorParagrahPlaceholderConfiguration; /// Whether the text can be changed. diff --git a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart index 9fec017ca..e4b64576e 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart @@ -55,9 +55,9 @@ class QuillRawEditorConfigurations extends Equatable { required this.characterShortcutEvents, required this.spaceShortcutEvents, required this.placeholderBuilder, + this.cursorParagrahPlaceholderConfiguration, @Deprecated( 'controller should be passed directly to the editor - this parameter will be removed in future versions.') - required this.cursorParagrahPlaceholderConfiguration, this.controller, this.showCursor = true, this.scrollable = true, @@ -168,7 +168,7 @@ class QuillRawEditorConfigurations extends Equatable { final List spaceShortcutEvents; /// This argument configure how will be showed the placeholder at right or left of the cursor - final CursorParagrahPlaceholderConfiguration + final CursorParagrahPlaceholderConfiguration? cursorParagrahPlaceholderConfiguration; /// Additional space around the editor contents. diff --git a/lib/src/editor/widgets/cursor.dart b/lib/src/editor/widgets/cursor.dart index 29929510d..ef54adb11 100644 --- a/lib/src/editor/widgets/cursor.dart +++ b/lib/src/editor/widgets/cursor.dart @@ -265,7 +265,7 @@ class CursorPainter { TextPosition position, bool lineHasEmbed, Line node, - CursorParagrahPlaceholderConfiguration cursorPlaceholderConfiguration, + CursorParagrahPlaceholderConfiguration? cursorPlaceholderConfiguration, TextDirection textDirection, ) { // relative (x, y) to global offset @@ -332,7 +332,7 @@ class CursorPainter { canvas.drawRRect(caretRRect, paint); } // we need to make these checks to avoid use this painter unnecessarily - if (cursorPlaceholderConfiguration.show && + if (cursorPlaceholderConfiguration != null && cursorPlaceholderConfiguration.show && cursorPlaceholderConfiguration.paragraphPlaceholderText .trim() .isNotEmpty) { diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index a4fa00060..72ce7f833 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -97,7 +97,7 @@ class EditableTextBlock extends StatelessWidget { final HorizontalSpacing horizontalSpacing; final VerticalSpacing verticalSpacing; final PlaceholderBuilder placeholderBuilder; - final CursorParagrahPlaceholderConfiguration + final CursorParagrahPlaceholderConfiguration? cursorParagrahPlaceholderConfiguration; final TextSelection textSelection; final Color color; diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 35390cbcf..9ab754493 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -688,7 +688,7 @@ class EditableTextLine extends RenderObjectWidget { final Widget body; final HorizontalSpacing horizontalSpacing; final VerticalSpacing verticalSpacing; - final CursorParagrahPlaceholderConfiguration + final CursorParagrahPlaceholderConfiguration? cursorParagrahPlaceholderConfiguration; final TextDirection textDirection; final TextSelection textSelection; @@ -772,7 +772,7 @@ class RenderEditableTextLine extends RenderEditableBox { TextSelection textSelection; Color color; bool enableInteractiveSelection; - CursorParagrahPlaceholderConfiguration cursorParagrahPlaceholderConfiguration; + CursorParagrahPlaceholderConfiguration? cursorParagrahPlaceholderConfiguration; bool hasFocus = false; double devicePixelRatio; EdgeInsetsGeometry padding; @@ -802,7 +802,7 @@ class RenderEditableTextLine extends RenderEditableBox { } void setCursorParagraphPlaceholderConfiguration( - CursorParagrahPlaceholderConfiguration c) { + CursorParagrahPlaceholderConfiguration? c) { if (cursorParagrahPlaceholderConfiguration == c) { return; } From 88e9cca0455c8dac369b2f42623470765294e918 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Wed, 18 Sep 2024 03:56:40 -0400 Subject: [PATCH 015/113] Chore: improve placeholders examples --- example/lib/screens/quill/quill_screen.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index f0bfcd976..af100489a 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/quill/quill_screen.dart @@ -131,11 +131,11 @@ class _QuillScreenState extends State { PlaceholderComponentsConfiguration( builders: { Attribute.header.key: (Attribute attr, style) { - final values = [30, 27, 22]; + final values = [32, 30, 24, 22, 18, 16]; final level = attr.value as int?; if (level == null) return null; final fontSize = values[ - (level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; + (level - 1 <= 0 ? 0 : level - 1)]; return PlaceholderArguments( placeholderText: 'Header $level', style: TextStyle(fontSize: fontSize.toDouble()) From 7be52d55c788ee823c8615e4cfaa724047b821d5 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Wed, 18 Sep 2024 12:29:35 -0400 Subject: [PATCH 016/113] Fix(merge): missing trailing comma on EditableTextLine constructor --- lib/src/editor/widgets/text/text_line.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index ee18a69d3..d5ace1848 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -722,7 +722,7 @@ class EditableTextLine extends RenderObjectWidget { cursorCont, inlineCodeStyle, composingRange, - composingColor + composingColor, cursorParagrahPlaceholderConfiguration); } From abf83637137c83037dd12ea01bcedc4d3abe93c8 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Wed, 18 Sep 2024 12:38:32 -0400 Subject: [PATCH 017/113] Chore: run before_push to fix formats --- example/lib/screens/quill/quill_screen.dart | 4 +-- .../editor/raw_editor/raw_editor_state.dart | 32 +++++++++---------- lib/src/editor/widgets/cursor.dart | 3 +- lib/src/editor/widgets/text/text_line.dart | 3 +- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index af100489a..9b59e7669 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/quill/quill_screen.dart @@ -134,8 +134,8 @@ class _QuillScreenState extends State { final values = [32, 30, 24, 22, 18, 16]; final level = attr.value as int?; if (level == null) return null; - final fontSize = values[ - (level - 1 <= 0 ? 0 : level - 1)]; + final fontSize = + values[(level - 1 <= 0 ? 0 : level - 1)]; return PlaceholderArguments( placeholderText: 'Header $level', style: TextStyle(fontSize: fontSize.toDouble()) diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 1575f744f..3c7625121 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -713,22 +713,22 @@ class QuillRawEditorState extends EditorState customLinkPrefixes: widget.configurations.customLinkPrefixes, ); final editableTextLine = EditableTextLine( - node, - null, - textLine, - _getHorizontalSpacingForLine(node, _styles), - _getVerticalSpacingForLine(node, _styles), - _textDirection, - controller.selection, - widget.configurations.selectionColor, - widget.configurations.enableInteractiveSelection, - _hasFocus, - MediaQuery.devicePixelRatioOf(context), - _cursorCont, - _styles!.inlineCode!, - composingRange.value, - _styles!.paragraph!.style.color!, - widget.configurations.cursorParagrahPlaceholderConfiguration, + node, + null, + textLine, + _getHorizontalSpacingForLine(node, _styles), + _getVerticalSpacingForLine(node, _styles), + _textDirection, + controller.selection, + widget.configurations.selectionColor, + widget.configurations.enableInteractiveSelection, + _hasFocus, + MediaQuery.devicePixelRatioOf(context), + _cursorCont, + _styles!.inlineCode!, + composingRange.value, + _styles!.paragraph!.style.color!, + widget.configurations.cursorParagrahPlaceholderConfiguration, ); return editableTextLine; } diff --git a/lib/src/editor/widgets/cursor.dart b/lib/src/editor/widgets/cursor.dart index ef54adb11..8152bf75b 100644 --- a/lib/src/editor/widgets/cursor.dart +++ b/lib/src/editor/widgets/cursor.dart @@ -332,7 +332,8 @@ class CursorPainter { canvas.drawRRect(caretRRect, paint); } // we need to make these checks to avoid use this painter unnecessarily - if (cursorPlaceholderConfiguration != null && cursorPlaceholderConfiguration.show && + if (cursorPlaceholderConfiguration != null && + cursorPlaceholderConfiguration.show && cursorPlaceholderConfiguration.paragraphPlaceholderText .trim() .isNotEmpty) { diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index d5ace1848..225bc2de9 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -781,7 +781,8 @@ class RenderEditableTextLine extends RenderEditableBox { TextSelection textSelection; Color color; bool enableInteractiveSelection; - CursorParagrahPlaceholderConfiguration? cursorParagrahPlaceholderConfiguration; + CursorParagrahPlaceholderConfiguration? + cursorParagrahPlaceholderConfiguration; bool hasFocus = false; double devicePixelRatio; EdgeInsetsGeometry padding; From d7c5d1458e5d6fb4ddaf21793ca9041e573ea8f7 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Wed, 18 Sep 2024 13:07:40 -0400 Subject: [PATCH 018/113] Chore: make placeholderComponentsConfiguration fully optional --- .../editor/config/editor_configurations.dart | 7 +- lib/src/editor/editor.dart | 332 ++++++------------ .../config/raw_editor_configurations.dart | 4 +- lib/src/editor/widgets/text/text_block.dart | 2 +- lib/src/editor/widgets/text/text_line.dart | 44 +-- 5 files changed, 137 insertions(+), 252 deletions(-) diff --git a/lib/src/editor/config/editor_configurations.dart b/lib/src/editor/config/editor_configurations.dart index 7349a9782..a1ab22c01 100644 --- a/lib/src/editor/config/editor_configurations.dart +++ b/lib/src/editor/config/editor_configurations.dart @@ -38,8 +38,7 @@ class QuillEditorConfigurations extends Equatable { this.padding = EdgeInsets.zero, this.characterShortcutEvents = const [], this.spaceShortcutEvents = const [], - this.placeholderComponentsConfiguration = - const PlaceholderComponentsConfiguration(builders: {}), + this.placeholderComponentsConfiguration, this.cursorParagrahPlaceholderConfiguration, this.autoFocus = false, this.expands = false, @@ -160,6 +159,8 @@ class QuillEditorConfigurations extends Equatable { /// Whether the line is empty, this let us add a placeholder /// + /// _Note: these placeholders are limited only to lines with block styles_ + /// /// ### Example /// /// Assume that you want to show only a placeholder text for the header items, @@ -184,7 +185,7 @@ class QuillEditorConfigurations extends Equatable { /// customBlockAttributesKeys: null, ///), ///``` - final PlaceholderComponentsConfiguration placeholderComponentsConfiguration; + final PlaceholderComponentsConfiguration? placeholderComponentsConfiguration; /// This argument configure how will be showed the placeholder at right or left of the cursor final CursorParagrahPlaceholderConfiguration? diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 82cf8cda9..aca1929dc 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -1,16 +1,9 @@ import 'dart:math' as math; -import 'package:flutter/cupertino.dart' - show CupertinoTheme, cupertinoTextSelectionControls; -import 'package:flutter/foundation.dart' - show ValueListenable, defaultTargetPlatform, kIsWeb; +import 'package:flutter/cupertino.dart' show CupertinoTheme, cupertinoTextSelectionControls; +import 'package:flutter/foundation.dart' show ValueListenable, defaultTargetPlatform, kIsWeb; import 'package:flutter/gestures.dart' - show - PointerDeviceKind, - TapDragDownDetails, - TapDragEndDetails, - TapDragStartDetails, - TapDragUpDetails; + show PointerDeviceKind, TapDragDownDetails, TapDragEndDetails, TapDragStartDetails, TapDragUpDetails; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; @@ -65,15 +58,14 @@ abstract class RenderAbstractEditor implements TextLayoutMetrics { /// and the returned list is of length two. In this case, however, the two /// points might actually be co-located (e.g., because of a bidirectional /// selection that contains some text but whose ends meet in the middle). - List getEndpointsForSelection( - TextSelection textSelection); + List getEndpointsForSelection(TextSelection textSelection); /// Sets the screen position of the floating cursor and the text position /// closest to the cursor. /// `resetLerpValue` drives the size of the floating cursor. /// See [EditorState.floatingCursorResetController]. - void setFloatingCursor(FloatingCursorDragState dragState, - Offset lastBoundedOffset, TextPosition lastTextPosition, + void setFloatingCursor( + FloatingCursorDragState dragState, Offset lastBoundedOffset, TextPosition lastTextPosition, {double? resetLerpValue}); /// If [ignorePointer] is false (the default) then this method is called by @@ -106,8 +98,7 @@ abstract class RenderAbstractEditor implements TextLayoutMetrics { /// yet reflected in the latest widget state. /// /// Returns null if no change occurred. - TextSelection? selectPositionAt( - {required Offset from, required SelectionChangedCause cause, Offset? to}); + TextSelection? selectPositionAt({required Offset from, required SelectionChangedCause cause, Offset? to}); /// Select a word around the location of the last tap down. /// @@ -161,26 +152,18 @@ class QuillEditor extends StatefulWidget { 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 ??= QuillController(document: Document(), selection: const TextSelection.collapsed(offset: 0)); // controller ..editorConfigurations = configurations ..editorFocusNode = focusNode; // return QuillEditor._( - focusNode: focusNode, - scrollController: scrollController, - controller: controller, - key: key); + focusNode: focusNode, scrollController: scrollController, controller: controller, key: key); } const QuillEditor._( - {required this.focusNode, - required this.scrollController, - required this.controller, - super.key}); + {required this.focusNode, required this.scrollController, required this.controller, super.key}); factory QuillEditor.basic({ /// The controller for the quill editor widget of flutter quill @@ -203,8 +186,7 @@ class QuillEditor extends StatefulWidget { final QuillController controller; /// The configurations for the quill editor widget of flutter quill - QuillEditorConfigurations get configurations => - controller.editorConfigurations; + QuillEditorConfigurations get configurations => controller.editorConfigurations; /// Controls whether this editor has keyboard focus. final FocusNode focusNode; @@ -216,11 +198,9 @@ class QuillEditor extends StatefulWidget { QuillEditorState createState() => QuillEditorState(); } -class QuillEditorState extends State - implements EditorTextSelectionGestureDetectorBuilderDelegate { +class QuillEditorState extends State implements EditorTextSelectionGestureDetectorBuilderDelegate { late GlobalKey _editorKey; - late EditorTextSelectionGestureDetectorBuilder - _selectionGestureDetectorBuilder; + late EditorTextSelectionGestureDetectorBuilder _selectionGestureDetectorBuilder; QuillController get controller => widget.controller; @@ -230,8 +210,7 @@ class QuillEditorState extends State void initState() { super.initState(); _editorKey = configurations.editorKey ?? GlobalKey(); - _selectionGestureDetectorBuilder = - _QuillEditorSelectionGestureDetectorBuilder( + _selectionGestureDetectorBuilder = _QuillEditorSelectionGestureDetectorBuilder( this, configurations.detectWordBoundary, ); @@ -253,8 +232,7 @@ class QuillEditorState extends State @override Widget build(BuildContext context) { final theme = Theme.of(context); - final selectionTheme = - configurations.textSelectionThemeData ?? TextSelectionTheme.of(context); + final selectionTheme = configurations.textSelectionThemeData ?? TextSelectionTheme.of(context); TextSelectionControls textSelectionControls; bool paintCursorAboveText; @@ -270,22 +248,23 @@ class QuillEditorState extends State paintCursorAboveText = true; cursorOpacityAnimates = true; cursorColor ??= selectionTheme.cursorColor ?? cupertinoTheme.primaryColor; - selectionColor = selectionTheme.selectionColor ?? - cupertinoTheme.primaryColor.withOpacity(0.40); + selectionColor = selectionTheme.selectionColor ?? cupertinoTheme.primaryColor.withOpacity(0.40); cursorRadius ??= const Radius.circular(2); - cursorOffset = Offset( - iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + cursorOffset = Offset(iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); } else { textSelectionControls = materialTextSelectionControls; paintCursorAboveText = false; cursorOpacityAnimates = false; cursorColor ??= selectionTheme.cursorColor ?? theme.colorScheme.primary; - selectionColor = selectionTheme.selectionColor ?? - theme.colorScheme.primary.withOpacity(0.40); + selectionColor = selectionTheme.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40); } - final showSelectionToolbar = configurations.enableInteractiveSelection && - configurations.enableSelectionToolbar; + final showSelectionToolbar = + configurations.enableInteractiveSelection && configurations.enableSelectionToolbar; + + final placeholderBuilder = widget.configurations.placeholderComponentsConfiguration == null + ? null + : PlaceholderBuilder(configuration: widget.configurations.placeholderComponentsConfiguration!); final child = FlutterQuillLocalizationsWidget( child: QuillEditorProvider( @@ -296,17 +275,11 @@ class QuillEditorState extends State key: _editorKey, controller: controller, configurations: QuillRawEditorConfigurations( - cursorParagrahPlaceholderConfiguration: - widget.configurations.cursorParagrahPlaceholderConfiguration, - placeholderBuilder: PlaceholderBuilder( - configuration: - widget.configurations.placeholderComponentsConfiguration, - ), - characterShortcutEvents: - widget.configurations.characterShortcutEvents, + cursorParagrahPlaceholderConfiguration: widget.configurations.cursorParagrahPlaceholderConfiguration, + placeholderBuilder: placeholderBuilder, + characterShortcutEvents: widget.configurations.characterShortcutEvents, spaceShortcutEvents: widget.configurations.spaceShortcutEvents, - customLeadingBuilder: - widget.configurations.customLeadingBlockBuilder, + customLeadingBuilder: widget.configurations.customLeadingBlockBuilder, focusNode: widget.focusNode, scrollController: widget.scrollController, scrollable: configurations.scrollable, @@ -319,8 +292,7 @@ class QuillEditorState extends State placeholder: configurations.placeholder, onLaunchUrl: configurations.onLaunchUrl, contextMenuBuilder: showSelectionToolbar - ? (configurations.contextMenuBuilder ?? - QuillRawEditorConfigurations.defaultContextMenuBuilder) + ? (configurations.contextMenuBuilder ?? QuillRawEditorConfigurations.defaultContextMenuBuilder) : null, showSelectionHandles: isMobile, showCursor: configurations.showCursor ?? true, @@ -330,8 +302,7 @@ class QuillEditorState extends State width: 2, radius: cursorRadius, offset: cursorOffset, - paintAboveText: - configurations.paintCursorAboveText ?? paintCursorAboveText, + paintAboveText: configurations.paintCursorAboveText ?? paintCursorAboveText, opacityAnimates: cursorOpacityAnimates, ), textCapitalization: configurations.textCapitalization, @@ -342,11 +313,9 @@ class QuillEditorState extends State expands: configurations.expands, autoFocus: configurations.autoFocus, selectionColor: selectionColor, - selectionCtrls: - configurations.textSelectionControls ?? textSelectionControls, + selectionCtrls: configurations.textSelectionControls ?? textSelectionControls, keyboardAppearance: configurations.keyboardAppearance, - enableInteractiveSelection: - configurations.enableInteractiveSelection, + enableInteractiveSelection: configurations.enableInteractiveSelection, scrollPhysics: configurations.scrollPhysics, embedBuilder: _getEmbedBuilder, linkActionPickerDelegate: configurations.linkActionPickerDelegate, @@ -361,8 +330,7 @@ class QuillEditorState extends State isOnTapOutsideEnabled: configurations.isOnTapOutsideEnabled, onTapOutside: configurations.onTapOutside, dialogTheme: configurations.dialogTheme, - contentInsertionConfiguration: - configurations.contentInsertionConfiguration, + contentInsertionConfiguration: configurations.contentInsertionConfiguration, enableScribble: configurations.enableScribble, onScribbleActivated: configurations.onScribbleActivated, scribbleAreaInsets: configurations.scribbleAreaInsets, @@ -445,10 +413,8 @@ class QuillEditorState extends State } } -class _QuillEditorSelectionGestureDetectorBuilder - extends EditorTextSelectionGestureDetectorBuilder { - _QuillEditorSelectionGestureDetectorBuilder( - this._state, this._detectWordBoundary) +class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGestureDetectorBuilder { + _QuillEditorSelectionGestureDetectorBuilder(this._state, this._detectWordBoundary) : super(delegate: _state, detectWordBoundary: _detectWordBoundary); final QuillEditorState _state; @@ -500,8 +466,7 @@ class _QuillEditorSelectionGestureDetectorBuilder return false; } final pos = renderEditor!.getPositionForOffset(details.globalPosition); - final result = - editor!.widget.controller.document.querySegmentLeafNode(pos.offset); + final result = editor!.widget.controller.document.querySegmentLeafNode(pos.offset); final line = result.line; if (line == null) { return false; @@ -534,8 +499,7 @@ class _QuillEditorSelectionGestureDetectorBuilder bool isShiftClick(PointerDeviceKind deviceKind) { final pressed = HardwareKeyboard.instance.logicalKeysPressed; return deviceKind == PointerDeviceKind.mouse && - (pressed.contains(LogicalKeyboardKey.shiftLeft) || - pressed.contains(LogicalKeyboardKey.shiftRight)); + (pressed.contains(LogicalKeyboardKey.shiftLeft) || pressed.contains(LogicalKeyboardKey.shiftRight)); } @override @@ -564,8 +528,7 @@ class _QuillEditorSelectionGestureDetectorBuilder // extend current selection instead. if (isShiftClick(details.kind)) { renderEditor! - ..extendSelection(details.globalPosition, - cause: SelectionChangedCause.tap) + ..extendSelection(details.globalPosition, cause: SelectionChangedCause.tap) ..onSelectionCompleted(); } else { renderEditor! @@ -673,8 +636,7 @@ class _QuillEditorSelectionGestureDetectorBuilder /// (including the cursor location). /// /// Used by [RenderEditor.onSelectionChanged]. -typedef TextSelectionChangedHandler = void Function( - TextSelection selection, SelectionChangedCause cause); +typedef TextSelectionChangedHandler = void Function(TextSelection selection, SelectionChangedCause cause); /// Signature for the callback that reports when a selection action is actually /// completed and ratified. Completion is defined as when the user input has @@ -693,8 +655,7 @@ const EdgeInsets _kFloatingCursorAddedMargin = EdgeInsets.fromLTRB(4, 4, 4, 5); // The additional size on the x and y axis with which to expand the prototype // cursor to render the floating cursor in pixels. -const EdgeInsets _kFloatingCaretSizeIncrease = - EdgeInsets.symmetric(horizontal: 0.5, vertical: 1); +const EdgeInsets _kFloatingCaretSizeIncrease = EdgeInsets.symmetric(horizontal: 0.5, vertical: 1); /// Displays a document as a vertical list of document segments (lines /// and blocks). @@ -719,8 +680,7 @@ class RenderEditor extends RenderEditableContainerBox required this.floatingCursorDisabled, ViewportOffset? offset, super.children, - EdgeInsets floatingCursorAddedMargin = - const EdgeInsets.fromLTRB(4, 4, 4, 5), + EdgeInsets floatingCursorAddedMargin = const EdgeInsets.fromLTRB(4, 4, 4, 5), double? maxContentWidth, }) : _hasFocus = hasFocus, _extendSelectionOrigin = selection, @@ -746,19 +706,16 @@ class RenderEditor extends RenderEditableContainerBox /// Called when the selection changes. TextSelectionChangedHandler onSelectionChanged; TextSelectionCompletedHandler onSelectionCompleted; - final ValueNotifier _selectionStartInViewport = - ValueNotifier(true); + final ValueNotifier _selectionStartInViewport = ValueNotifier(true); - ValueListenable get selectionStartInViewport => - _selectionStartInViewport; + ValueListenable get selectionStartInViewport => _selectionStartInViewport; ValueListenable get selectionEndInViewport => _selectionEndInViewport; final ValueNotifier _selectionEndInViewport = ValueNotifier(true); void _updateSelectionExtentsVisibility(Offset effectiveOffset) { final visibleRegion = Offset.zero & size; - final startPosition = - TextPosition(offset: selection.start, affinity: selection.affinity); + final startPosition = TextPosition(offset: selection.start, affinity: selection.affinity); final startOffset = _getOffsetForCaret(startPosition); // TODO(justinmc): https://github.com/flutter/flutter/issues/31495 // Check if the selection is visible with an approximation because a @@ -768,16 +725,12 @@ class RenderEditor extends RenderEditableContainerBox // _applyFloatingPointHack. Ideally, the rounding mismatch will be fixed and // this can be changed to be a strict check instead of an approximation. const visibleRegionSlop = 0.5; - _selectionStartInViewport.value = visibleRegion - .inflate(visibleRegionSlop) - .contains(startOffset + effectiveOffset); + _selectionStartInViewport.value = + visibleRegion.inflate(visibleRegionSlop).contains(startOffset + effectiveOffset); - final endPosition = - TextPosition(offset: selection.end, affinity: selection.affinity); + final endPosition = TextPosition(offset: selection.end, affinity: selection.affinity); final endOffset = _getOffsetForCaret(endPosition); - _selectionEndInViewport.value = visibleRegion - .inflate(visibleRegionSlop) - .contains(endOffset + effectiveOffset); + _selectionEndInViewport.value = visibleRegion.inflate(visibleRegionSlop).contains(endOffset + effectiveOffset); } // returns offset relative to this at which the caret will be painted @@ -834,10 +787,8 @@ class RenderEditor extends RenderEditableContainerBox } bool get _shiftPressed => - HardwareKeyboard.instance.logicalKeysPressed - .contains(LogicalKeyboardKey.shiftLeft) || - HardwareKeyboard.instance.logicalKeysPressed - .contains(LogicalKeyboardKey.shiftRight); + HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.shiftLeft) || + HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.shiftRight); void setStartHandleLayerLink(LayerLink value) { if (_startHandleLayerLink == value) { @@ -872,8 +823,7 @@ class RenderEditor extends RenderEditableContainerBox } @override - List getEndpointsForSelection( - TextSelection textSelection) { + List getEndpointsForSelection(TextSelection textSelection) { if (textSelection.isCollapsed) { final child = childAtPosition(textSelection.extent); final localPosition = TextPosition( @@ -884,10 +834,7 @@ class RenderEditor extends RenderEditableContainerBox final parentData = child.parentData as BoxParentData; return [ TextSelectionPoint( - Offset(0, child.preferredLineHeight(localPosition)) + - localOffset + - parentData.offset, - null) + Offset(0, child.preferredLineHeight(localPosition)) + localOffset + parentData.offset, null) ]; } @@ -903,8 +850,7 @@ class RenderEditor extends RenderEditableContainerBox assert(baseChild != null); final baseParentData = baseChild!.parentData as BoxParentData; - final baseSelection = - localSelection(baseChild.container, textSelection, true); + final baseSelection = localSelection(baseChild.container, textSelection, true); var basePoint = baseChild.getBaseEndpointForSelection(baseSelection); basePoint = TextSelectionPoint( basePoint.point + baseParentData.offset, @@ -933,10 +879,8 @@ class RenderEditor extends RenderEditableContainerBox assert(extentChild != null); final extentParentData = extentChild!.parentData as BoxParentData; - final extentSelection = - localSelection(extentChild.container, textSelection, true); - var extentPoint = - extentChild.getExtentEndpointForSelection(extentSelection); + final extentSelection = localSelection(extentChild.container, textSelection, true); + var extentPoint = extentChild.getExtentEndpointForSelection(extentSelection); extentPoint = TextSelectionPoint( extentPoint.point + extentParentData.offset, extentPoint.direction, @@ -993,8 +937,7 @@ class RenderEditor extends RenderEditableContainerBox ) { final firstPosition = getPositionForOffset(from); final firstWord = selectWordAtPosition(firstPosition); - final lastWord = - to == null ? firstWord : selectWordAtPosition(getPositionForOffset(to)); + final lastWord = to == null ? firstWord : selectWordAtPosition(getPositionForOffset(to)); _handleSelectionChange( TextSelection( @@ -1010,12 +953,8 @@ class RenderEditor extends RenderEditableContainerBox TextSelection nextSelection, SelectionChangedCause cause, ) { - final focusingEmpty = nextSelection.baseOffset == 0 && - nextSelection.extentOffset == 0 && - !_hasFocus; - if (nextSelection == selection && - cause != SelectionChangedCause.keyboard && - !focusingEmpty) { + final focusingEmpty = nextSelection.baseOffset == 0 && nextSelection.extentOffset == 0 && !_hasFocus; + if (nextSelection == selection && cause != SelectionChangedCause.keyboard && !focusingEmpty) { return; } onSelectionChanged(nextSelection, cause); @@ -1066,8 +1005,7 @@ class RenderEditor extends RenderEditableContainerBox ); // Don't change selection if the selected word is a placeholder. - if (child.container.style.attributes - .containsKey(Attribute.placeholder.key)) { + if (child.container.style.attributes.containsKey(Attribute.placeholder.key)) { return; } @@ -1078,8 +1016,7 @@ class RenderEditor extends RenderEditableContainerBox ); } else { _handleSelectionChange( - TextSelection.collapsed( - offset: word.end, affinity: TextAffinity.upstream), + TextSelection.collapsed(offset: word.end, affinity: TextAffinity.upstream), cause, ); } @@ -1154,8 +1091,7 @@ class RenderEditor extends RenderEditableContainerBox ' resize its children, so it must be ' 'placed in a parent that does not constrain the main ' 'axis.'), - ErrorHint( - 'You probably want to put the RenderEditableContainerBox inside a ' + ErrorHint('You probably want to put the RenderEditableContainerBox inside a ' 'RenderViewport with a matching main axis or disable the ' 'scrollable property.') ]); @@ -1177,13 +1113,11 @@ class RenderEditor extends RenderEditableContainerBox var mainAxisExtent = resolvedPadding!.top; var child = firstChild; - final innerConstraints = BoxConstraints.tightFor( - width: math.min( - _maxContentWidth ?? double.infinity, constraints.maxWidth)) - .deflate(resolvedPadding!); - final leftOffset = _maxContentWidth == null - ? 0.0 - : math.max((constraints.maxWidth - _maxContentWidth!) / 2, 0); + final innerConstraints = + BoxConstraints.tightFor(width: math.min(_maxContentWidth ?? double.infinity, constraints.maxWidth)) + .deflate(resolvedPadding!); + final leftOffset = + _maxContentWidth == null ? 0.0 : math.max((constraints.maxWidth - _maxContentWidth!) / 2, 0); while (child != null) { child.layout(innerConstraints, parentUsesSize: true); final childParentData = child.parentData as EditableContainerParentData @@ -1200,18 +1134,14 @@ class RenderEditor extends RenderEditableContainerBox @override void paint(PaintingContext context, Offset offset) { - if (_hasFocus && - _cursorController.show.value && - !_cursorController.style.paintAboveText) { + if (_hasFocus && _cursorController.show.value && !_cursorController.style.paintAboveText) { _paintFloatingCursor(context, offset); } defaultPaint(context, offset); _updateSelectionExtentsVisibility(offset + _paintOffset); _paintHandleLayers(context, getEndpointsForSelection(selection)); - if (_hasFocus && - _cursorController.show.value && - _cursorController.style.paintAboveText) { + if (_hasFocus && _cursorController.show.value && _cursorController.style.paintAboveText) { _paintFloatingCursor(context, offset); } } @@ -1221,8 +1151,7 @@ class RenderEditor extends RenderEditableContainerBox return defaultHitTestChildren(result, position: position); } - void _paintHandleLayers( - PaintingContext context, List endpoints) { + void _paintHandleLayers(PaintingContext context, List endpoints) { var startPoint = endpoints[0].point; startPoint = Offset( startPoint.dx.clamp(0.0, size.width), @@ -1250,8 +1179,7 @@ class RenderEditor extends RenderEditableContainerBox @override double preferredLineHeight(TextPosition position) { final child = childAtPosition(position); - return child.preferredLineHeight( - TextPosition(offset: position.offset - child.container.offset)); + return child.preferredLineHeight(TextPosition(offset: position.offset - child.container.offset)); } @override @@ -1286,8 +1214,7 @@ class RenderEditor extends RenderEditableContainerBox /// this editor from above it. /// /// Returns `null` if the cursor is currently visible. - double? getOffsetToRevealCursor( - double viewportHeight, double scrollOffset, double offsetInViewport) { + double? getOffsetToRevealCursor(double viewportHeight, double scrollOffset, double offsetInViewport) { // Endpoints coordinates represents lower left or lower right corner of // the selection. If we want to scroll up to reveal the caret we need to // adjust the dy value by the height of the line. We also add a small margin @@ -1300,9 +1227,7 @@ class RenderEditor extends RenderEditableContainerBox endpoint = endpoints.first; } else { if (selection is DragTextSelection) { - endpoint = (selection as DragTextSelection).first - ? endpoints.first - : endpoints.last; + endpoint = (selection as DragTextSelection).first ? endpoints.first : endpoints.last; } else { endpoint = endpoints.first; } @@ -1313,13 +1238,11 @@ class RenderEditor extends RenderEditableContainerBox const kMargin = 8.0; final caretTop = endpoint.point.dy - - child.preferredLineHeight(TextPosition( - offset: selection.extentOffset - child.container.documentOffset)) - + child.preferredLineHeight(TextPosition(offset: selection.extentOffset - child.container.documentOffset)) - kMargin + offsetInViewport + scrollBottomInset; - final caretBottom = - endpoint.point.dy + kMargin + offsetInViewport + scrollBottomInset; + final caretBottom = endpoint.point.dy + kMargin + offsetInViewport + scrollBottomInset; double? dy; if (caretTop < scrollOffset) { dy = caretTop; @@ -1369,12 +1292,10 @@ class RenderEditor extends RenderEditableContainerBox bool _resetOriginOnBottom = false; /// Returns the position within the editor closest to the raw cursor offset. - Offset calculateBoundedFloatingCursorOffset( - Offset rawCursorOffset, double preferredLineHeight) { + Offset calculateBoundedFloatingCursorOffset(Offset rawCursorOffset, double preferredLineHeight) { var deltaPosition = Offset.zero; final topBound = _kFloatingCursorAddedMargin.top; - final bottomBound = - size.height - preferredLineHeight + _kFloatingCursorAddedMargin.bottom; + final bottomBound = size.height - preferredLineHeight + _kFloatingCursorAddedMargin.bottom; final leftBound = _kFloatingCursorAddedMargin.left; final rightBound = size.width - _kFloatingCursorAddedMargin.right; @@ -1386,30 +1307,24 @@ class RenderEditor extends RenderEditableContainerBox // we want to reset the relative origin of // the dragging when the user drags back into the field. if (_resetOriginOnLeft && deltaPosition.dx > 0) { - _relativeOrigin = - Offset(rawCursorOffset.dx - leftBound, _relativeOrigin.dy); + _relativeOrigin = Offset(rawCursorOffset.dx - leftBound, _relativeOrigin.dy); _resetOriginOnLeft = false; } else if (_resetOriginOnRight && deltaPosition.dx < 0) { - _relativeOrigin = - Offset(rawCursorOffset.dx - rightBound, _relativeOrigin.dy); + _relativeOrigin = Offset(rawCursorOffset.dx - rightBound, _relativeOrigin.dy); _resetOriginOnRight = false; } if (_resetOriginOnTop && deltaPosition.dy > 0) { - _relativeOrigin = - Offset(_relativeOrigin.dx, rawCursorOffset.dy - topBound); + _relativeOrigin = Offset(_relativeOrigin.dx, rawCursorOffset.dy - topBound); _resetOriginOnTop = false; } else if (_resetOriginOnBottom && deltaPosition.dy < 0) { - _relativeOrigin = - Offset(_relativeOrigin.dx, rawCursorOffset.dy - bottomBound); + _relativeOrigin = Offset(_relativeOrigin.dx, rawCursorOffset.dy - bottomBound); _resetOriginOnBottom = false; } final currentX = rawCursorOffset.dx - _relativeOrigin.dx; final currentY = rawCursorOffset.dy - _relativeOrigin.dy; - final double adjustedX = - math.min(math.max(currentX, leftBound), rightBound); - final double adjustedY = - math.min(math.max(currentY, topBound), bottomBound); + final double adjustedX = math.min(math.max(currentX, leftBound), rightBound); + final double adjustedY = math.min(math.max(currentY, topBound), bottomBound); final adjustedOffset = Offset(adjustedX, adjustedY); if (currentX < leftBound && deltaPosition.dx < 0) { @@ -1429,8 +1344,7 @@ class RenderEditor extends RenderEditableContainerBox } @override - void setFloatingCursor(FloatingCursorDragState dragState, - Offset boundedOffset, TextPosition textPosition, + void setFloatingCursor(FloatingCursorDragState dragState, Offset boundedOffset, TextPosition textPosition, {double? resetLerpValue}) { if (floatingCursorDisabled) return; @@ -1446,17 +1360,13 @@ class RenderEditor extends RenderEditableContainerBox if (_floatingCursorOn) { _floatingCursorTextPosition = textPosition; final sizeAdjustment = resetLerpValue != null - ? EdgeInsets.lerp( - _kFloatingCaretSizeIncrease, EdgeInsets.zero, resetLerpValue)! + ? EdgeInsets.lerp(_kFloatingCaretSizeIncrease, EdgeInsets.zero, resetLerpValue)! : _kFloatingCaretSizeIncrease; final child = childAtPosition(textPosition); - final caretPrototype = - child.getCaretPrototype(child.globalToLocalPosition(textPosition)); - _floatingCursorRect = - sizeAdjustment.inflateRect(caretPrototype).shift(boundedOffset); + final caretPrototype = child.getCaretPrototype(child.globalToLocalPosition(textPosition)); + _floatingCursorRect = sizeAdjustment.inflateRect(caretPrototype).shift(boundedOffset); - _cursorController - .setFloatingCursorTextPosition(_floatingCursorTextPosition); + _cursorController.setFloatingCursorTextPosition(_floatingCursorTextPosition); } else { _floatingCursorRect = null; _cursorController.setFloatingCursorTextPosition(null); @@ -1477,8 +1387,7 @@ class RenderEditor extends RenderEditableContainerBox TextSelection getLineAtOffset(TextPosition position) { final child = childAtPosition(position); final nodeOffset = child.container.offset; - final localPosition = TextPosition( - offset: position.offset - nodeOffset, affinity: position.affinity); + final localPosition = TextPosition(offset: position.offset - nodeOffset, affinity: position.affinity); final localLineRange = child.getLineBoundary(localPosition); final line = TextRange( start: localLineRange.start + nodeOffset, @@ -1491,8 +1400,7 @@ class RenderEditor extends RenderEditableContainerBox TextRange getWordBoundary(TextPosition position) { final child = childAtPosition(position); final nodeOffset = child.container.offset; - final localPosition = TextPosition( - offset: position.offset - nodeOffset, affinity: position.affinity); + final localPosition = TextPosition(offset: position.offset - nodeOffset, affinity: position.affinity); final localWord = child.getWordBoundary(localPosition); return TextRange( start: localWord.start + nodeOffset, @@ -1501,8 +1409,7 @@ class RenderEditor extends RenderEditableContainerBox } /// Returns the TextPosition after moving by the vertical offset. - TextPosition getTextPositionMoveVertical( - TextPosition position, double verticalOffset) { + TextPosition getTextPositionMoveVertical(TextPosition position, double verticalOffset) { final caretOfs = localToGlobal(_getOffsetForCaret(position)); return getPositionForOffset(caretOfs.translate(0, verticalOffset)); } @@ -1514,8 +1421,7 @@ class RenderEditor extends RenderEditableContainerBox @override TextPosition getTextPositionAbove(TextPosition position) { final child = childAtPosition(position); - final localPosition = - TextPosition(offset: position.offset - child.container.documentOffset); + final localPosition = TextPosition(offset: position.offset - child.container.documentOffset); var newPosition = child.getPositionAbove(localPosition); @@ -1533,12 +1439,10 @@ class RenderEditor extends RenderEditableContainerBox final testOffset = sibling.getOffsetForCaret(testPosition); final finalOffset = Offset(caretOffset.dx, testOffset.dy); final siblingPosition = sibling.getPositionForOffset(finalOffset); - newPosition = TextPosition( - offset: sibling.container.documentOffset + siblingPosition.offset); + newPosition = TextPosition(offset: sibling.container.documentOffset + siblingPosition.offset); } } else { - newPosition = TextPosition( - offset: child.container.documentOffset + newPosition.offset); + newPosition = TextPosition(offset: child.container.documentOffset + newPosition.offset); } return newPosition; } @@ -1583,8 +1487,7 @@ class RenderEditor extends RenderEditableContainerBox // End TextLayoutMetrics implementation - QuillVerticalCaretMovementRun startVerticalCaretMovement( - TextPosition startPosition) { + QuillVerticalCaretMovementRun startVerticalCaretMovement(TextPosition startPosition) { return QuillVerticalCaretMovementRun._( this, startPosition, @@ -1625,23 +1528,19 @@ class QuillVerticalCaretMovementRun implements Iterator { } void moveVertical(double verticalOffset) { - _currentTextPosition = _editor.getTextPositionMoveVertical( - _currentTextPosition, verticalOffset); + _currentTextPosition = _editor.getTextPositionMoveVertical(_currentTextPosition, verticalOffset); } } -class EditableContainerParentData - extends ContainerBoxParentData {} +class EditableContainerParentData extends ContainerBoxParentData {} /// Multi-child render box of editable content. /// /// Common ancestor for [RenderEditor] and [RenderEditableTextBlock]. class RenderEditableContainerBox extends RenderBox with - ContainerRenderObjectMixin, - RenderBoxContainerDefaultsMixin { + ContainerRenderObjectMixin, + RenderBoxContainerDefaultsMixin { RenderEditableContainerBox({ required container_node.QuillContainer container, required this.textDirection, @@ -1770,9 +1669,7 @@ class RenderEditableContainerBox extends RenderBox var mainAxisExtent = _resolvedPadding!.top; var child = firstChild; - final innerConstraints = - BoxConstraints.tightFor(width: constraints.maxWidth) - .deflate(_resolvedPadding!); + final innerConstraints = BoxConstraints.tightFor(width: constraints.maxWidth).deflate(_resolvedPadding!); while (child != null) { child.layout(innerConstraints, parentUsesSize: true); final childParentData = (child.parentData as EditableContainerParentData) @@ -1813,11 +1710,8 @@ class RenderEditableContainerBox extends RenderBox double computeMinIntrinsicWidth(double height) { resolvePadding(); return _getIntrinsicCrossAxis((child) { - final childHeight = math.max( - 0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); - return child.getMinIntrinsicWidth(childHeight) + - _resolvedPadding!.left + - _resolvedPadding!.right; + final childHeight = math.max(0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); + return child.getMinIntrinsicWidth(childHeight) + _resolvedPadding!.left + _resolvedPadding!.right; }); } @@ -1825,11 +1719,8 @@ class RenderEditableContainerBox extends RenderBox double computeMaxIntrinsicWidth(double height) { resolvePadding(); return _getIntrinsicCrossAxis((child) { - final childHeight = math.max( - 0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); - return child.getMaxIntrinsicWidth(childHeight) + - _resolvedPadding!.left + - _resolvedPadding!.right; + final childHeight = math.max(0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); + return child.getMaxIntrinsicWidth(childHeight) + _resolvedPadding!.left + _resolvedPadding!.right; }); } @@ -1837,11 +1728,8 @@ class RenderEditableContainerBox extends RenderBox double computeMinIntrinsicHeight(double width) { resolvePadding(); return _getIntrinsicMainAxis((child) { - final childWidth = math.max( - 0, width - _resolvedPadding!.left + _resolvedPadding!.right); - return child.getMinIntrinsicHeight(childWidth) + - _resolvedPadding!.top + - _resolvedPadding!.bottom; + final childWidth = math.max(0, width - _resolvedPadding!.left + _resolvedPadding!.right); + return child.getMinIntrinsicHeight(childWidth) + _resolvedPadding!.top + _resolvedPadding!.bottom; }); } @@ -1849,18 +1737,14 @@ class RenderEditableContainerBox extends RenderBox double computeMaxIntrinsicHeight(double width) { resolvePadding(); return _getIntrinsicMainAxis((child) { - final childWidth = math.max( - 0, width - _resolvedPadding!.left + _resolvedPadding!.right); - return child.getMaxIntrinsicHeight(childWidth) + - _resolvedPadding!.top + - _resolvedPadding!.bottom; + final childWidth = math.max(0, width - _resolvedPadding!.left + _resolvedPadding!.right); + return child.getMaxIntrinsicHeight(childWidth) + _resolvedPadding!.top + _resolvedPadding!.bottom; }); } @override double computeDistanceToActualBaseline(TextBaseline baseline) { resolvePadding(); - return defaultComputeDistanceToFirstActualBaseline(baseline)! + - _resolvedPadding!.top; + return defaultComputeDistanceToFirstActualBaseline(baseline)! + _resolvedPadding!.top; } } diff --git a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart index e4b64576e..aa9a460fd 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_configurations.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_configurations.dart @@ -54,7 +54,7 @@ class QuillRawEditorConfigurations extends Equatable { required this.autoFocus, required this.characterShortcutEvents, required this.spaceShortcutEvents, - required this.placeholderBuilder, + this.placeholderBuilder, this.cursorParagrahPlaceholderConfiguration, @Deprecated( 'controller should be passed directly to the editor - this parameter will be removed in future versions.') @@ -143,7 +143,7 @@ class QuillRawEditorConfigurations extends Equatable { /// Contains all necessary logic to build the placeholder /// given for the devs - final PlaceholderBuilder placeholderBuilder; + final PlaceholderBuilder? placeholderBuilder; /// Contains all the events that will be handled when /// space key is pressed diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index d46eb3768..799ad2e2e 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -97,7 +97,7 @@ class EditableTextBlock extends StatelessWidget { final double scrollBottomInset; final HorizontalSpacing horizontalSpacing; final VerticalSpacing verticalSpacing; - final PlaceholderBuilder placeholderBuilder; + final PlaceholderBuilder? placeholderBuilder; final CursorParagrahPlaceholderConfiguration? cursorParagrahPlaceholderConfiguration; final TextSelection textSelection; diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 225bc2de9..45da68e94 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -32,7 +32,7 @@ class TextLine extends StatefulWidget { required this.controller, required this.onLaunchUrl, required this.linkActionPicker, - required this.placeholderBuilder, + this.placeholderBuilder, this.textDirection, this.customStyleBuilder, this.customRecognizerBuilder, @@ -42,7 +42,7 @@ class TextLine extends StatefulWidget { final Line line; final TextDirection? textDirection; - final PlaceholderBuilder placeholderBuilder; + final PlaceholderBuilder? placeholderBuilder; final EmbedsBuilder embedBuilder; final DefaultStyles styles; final bool readOnly; @@ -267,28 +267,28 @@ class _TextLineState extends State { LinkedList nodes, TextStyle lineStyle, ) { - var addWebNodeIfNeeded = false; - if (nodes.isEmpty && widget.placeholderBuilder.builders.isNotEmpty) { - final (shouldShowNode, attrKey) = - widget.placeholderBuilder.shouldShowPlaceholder(widget.line); - if (shouldShowNode) { - final style = _getInlineTextStyle( - const Style(), defaultStyles, widget.line.style, false); - final placeholderWidget = widget.placeholderBuilder.build( - blockAttribute: widget.line.style.attributes[attrKey]!, - lineStyle: lineStyle.merge(style), - textDirection: widget.textDirection ?? Directionality.of(context), + var addWebNodeIfNeeded = widget.placeholderBuilder == null; + if (widget.placeholderBuilder != null && nodes.isEmpty && widget.placeholderBuilder!.builders.isNotEmpty) { + final (shouldShowNode, attrKey) = + widget.placeholderBuilder!.shouldShowPlaceholder(widget.line); + if (shouldShowNode) { + final style = _getInlineTextStyle( + const Style(), defaultStyles, widget.line.style, false); + final placeholderWidget = widget.placeholderBuilder!.build( + blockAttribute: widget.line.style.attributes[attrKey]!, + lineStyle: lineStyle.merge(style), + textDirection: widget.textDirection ?? Directionality.of(context), + ); + if (placeholderWidget != null) { + final widgetSpan = _getTextSpanFromNode( + defaultStyles, + leaf.QuillText(), + widget.line.style, + placeholderWidget: placeholderWidget, ); - if (placeholderWidget != null) { - final widgetSpan = _getTextSpanFromNode( - defaultStyles, - leaf.QuillText(), - widget.line.style, - placeholderWidget: placeholderWidget, - ); - return TextSpan(children: [widgetSpan], style: lineStyle); - } + return TextSpan(children: [widgetSpan], style: lineStyle); } + } // if the [placeholderWidget] is null or [shouldShowNode] is false // then this line will be executed and avoid non add // the needed node when the line is empty From 1eefa9d9f41e7a3e9638f6e34bb3fc0d0ecb589b Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 19 Sep 2024 14:11:42 -0400 Subject: [PATCH 019/113] Fix: add validation to avoid show component placeholder when found combinable styles --- .../placeholder_builder_internal.dart | 47 ++++++++++--------- lib/src/editor/widgets/text/text_line.dart | 4 +- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 7076cc47f..34fa7bde7 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -1,14 +1,7 @@ // This file is only for internal use import 'package:flutter/material.dart' - show - Expanded, - Row, - Text, - TextDirection, - TextStyle, - TextWidthBasis, - Widget, - immutable; + show Expanded, Row, Text, TextDirection, TextStyle, TextWidthBasis, Widget, immutable; +import 'package:meta/meta.dart'; import '../../../../document/attribute.dart' show Attribute, AttributeScope; import '../../../../document/nodes/line.dart'; import 'placeholder_configuration.dart'; @@ -33,20 +26,16 @@ class PlaceholderBuilder { final PlaceholderComponentsConfiguration configuration; - Map get builders => - configuration.builders; - Set? get customBlockAttributesKeys => - configuration.customBlockAttributesKeys; + Map get builders => configuration.builders; + Set? get customBlockAttributesKeys => configuration.customBlockAttributesKeys; /// Check if this node need to show a placeholder + @experimental (bool, String) shouldShowPlaceholder(Line node) { - if (builders.isEmpty) return (false, ''); + if (builders.isEmpty || _validateCombinableStyles(node)) return (false, ''); var shouldShow = false; var key = ''; - for (final exclusiveKey in { - ...Attribute.exclusiveBlockKeys, - ...?customBlockAttributesKeys - }) { + for (final exclusiveKey in {...Attribute.exclusiveBlockKeys, ...?customBlockAttributesKeys}) { if (node.style.containsKey(exclusiveKey) && node.style.attributes[exclusiveKey]?.scope == AttributeScope.block && !_blackList.contains(exclusiveKey)) { @@ -60,17 +49,33 @@ class PlaceholderBuilder { return (node.isEmpty && shouldShow, key); } + /// We use this to validate if the node contains + /// styles that can be combined with other block styles + @experimental + bool _validateCombinableStyles(Line node) { + for (final exclusiveKey in [ + Attribute.indent.key, + Attribute.align.key, + Attribute.lineHeight.key, + ]) { + if (node.style.containsKey(exclusiveKey)) { + return true; + } + } + return false; + } + + @experimental Widget? build({ required Attribute blockAttribute, required TextStyle lineStyle, required TextDirection textDirection, }) { if (builders.isEmpty) return null; - final configuration = - builders[blockAttribute.key]?.call(blockAttribute, lineStyle); + final configuration = builders[blockAttribute.key]?.call(blockAttribute, lineStyle); // we return a row because this widget takes the whole width and makes possible // select the block correctly (without this the block line cannot be selected correctly) - return configuration == null + return configuration == null || configuration.placeholderText.trim().isEmpty ? null : Row( children: [ diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 45da68e94..301ec1d64 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -282,7 +282,7 @@ class _TextLineState extends State { if (placeholderWidget != null) { final widgetSpan = _getTextSpanFromNode( defaultStyles, - leaf.QuillText(), + leaf.QuillText(''), widget.line.style, placeholderWidget: placeholderWidget, ); @@ -453,7 +453,7 @@ class _TextLineState extends State { } } if (placeholderWidget != null) { - return WidgetSpan(child: placeholderWidget); + return WidgetSpan(child: placeholderWidget, style: style); } if (!isLink && From cece3588393ba734d3200abd424e1be38c0a8e8b Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 19 Sep 2024 15:31:50 -0400 Subject: [PATCH 020/113] Chore: dart format --- lib/src/editor/editor.dart | 332 ++++++++++++------ .../placeholder_builder_internal.dart | 26 +- lib/src/editor/widgets/text/text_line.dart | 40 ++- 3 files changed, 267 insertions(+), 131 deletions(-) diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index aca1929dc..f9e4a0605 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -1,9 +1,16 @@ import 'dart:math' as math; -import 'package:flutter/cupertino.dart' show CupertinoTheme, cupertinoTextSelectionControls; -import 'package:flutter/foundation.dart' show ValueListenable, defaultTargetPlatform, kIsWeb; +import 'package:flutter/cupertino.dart' + show CupertinoTheme, cupertinoTextSelectionControls; +import 'package:flutter/foundation.dart' + show ValueListenable, defaultTargetPlatform, kIsWeb; import 'package:flutter/gestures.dart' - show PointerDeviceKind, TapDragDownDetails, TapDragEndDetails, TapDragStartDetails, TapDragUpDetails; + show + PointerDeviceKind, + TapDragDownDetails, + TapDragEndDetails, + TapDragStartDetails, + TapDragUpDetails; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; @@ -58,14 +65,15 @@ abstract class RenderAbstractEditor implements TextLayoutMetrics { /// and the returned list is of length two. In this case, however, the two /// points might actually be co-located (e.g., because of a bidirectional /// selection that contains some text but whose ends meet in the middle). - List getEndpointsForSelection(TextSelection textSelection); + List getEndpointsForSelection( + TextSelection textSelection); /// Sets the screen position of the floating cursor and the text position /// closest to the cursor. /// `resetLerpValue` drives the size of the floating cursor. /// See [EditorState.floatingCursorResetController]. - void setFloatingCursor( - FloatingCursorDragState dragState, Offset lastBoundedOffset, TextPosition lastTextPosition, + void setFloatingCursor(FloatingCursorDragState dragState, + Offset lastBoundedOffset, TextPosition lastTextPosition, {double? resetLerpValue}); /// If [ignorePointer] is false (the default) then this method is called by @@ -98,7 +106,8 @@ abstract class RenderAbstractEditor implements TextLayoutMetrics { /// yet reflected in the latest widget state. /// /// Returns null if no change occurred. - TextSelection? selectPositionAt({required Offset from, required SelectionChangedCause cause, Offset? to}); + TextSelection? selectPositionAt( + {required Offset from, required SelectionChangedCause cause, Offset? to}); /// Select a word around the location of the last tap down. /// @@ -152,18 +161,26 @@ class QuillEditor extends StatefulWidget { 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 ??= QuillController( + document: Document(), + selection: const TextSelection.collapsed(offset: 0)); // controller ..editorConfigurations = configurations ..editorFocusNode = focusNode; // return QuillEditor._( - focusNode: focusNode, scrollController: scrollController, controller: controller, key: key); + focusNode: focusNode, + scrollController: scrollController, + controller: controller, + key: key); } const QuillEditor._( - {required this.focusNode, required this.scrollController, required this.controller, super.key}); + {required this.focusNode, + required this.scrollController, + required this.controller, + super.key}); factory QuillEditor.basic({ /// The controller for the quill editor widget of flutter quill @@ -186,7 +203,8 @@ class QuillEditor extends StatefulWidget { final QuillController controller; /// The configurations for the quill editor widget of flutter quill - QuillEditorConfigurations get configurations => controller.editorConfigurations; + QuillEditorConfigurations get configurations => + controller.editorConfigurations; /// Controls whether this editor has keyboard focus. final FocusNode focusNode; @@ -198,9 +216,11 @@ class QuillEditor extends StatefulWidget { QuillEditorState createState() => QuillEditorState(); } -class QuillEditorState extends State implements EditorTextSelectionGestureDetectorBuilderDelegate { +class QuillEditorState extends State + implements EditorTextSelectionGestureDetectorBuilderDelegate { late GlobalKey _editorKey; - late EditorTextSelectionGestureDetectorBuilder _selectionGestureDetectorBuilder; + late EditorTextSelectionGestureDetectorBuilder + _selectionGestureDetectorBuilder; QuillController get controller => widget.controller; @@ -210,7 +230,8 @@ class QuillEditorState extends State implements EditorTextSelection void initState() { super.initState(); _editorKey = configurations.editorKey ?? GlobalKey(); - _selectionGestureDetectorBuilder = _QuillEditorSelectionGestureDetectorBuilder( + _selectionGestureDetectorBuilder = + _QuillEditorSelectionGestureDetectorBuilder( this, configurations.detectWordBoundary, ); @@ -232,7 +253,8 @@ class QuillEditorState extends State implements EditorTextSelection @override Widget build(BuildContext context) { final theme = Theme.of(context); - final selectionTheme = configurations.textSelectionThemeData ?? TextSelectionTheme.of(context); + final selectionTheme = + configurations.textSelectionThemeData ?? TextSelectionTheme.of(context); TextSelectionControls textSelectionControls; bool paintCursorAboveText; @@ -248,23 +270,29 @@ class QuillEditorState extends State implements EditorTextSelection paintCursorAboveText = true; cursorOpacityAnimates = true; cursorColor ??= selectionTheme.cursorColor ?? cupertinoTheme.primaryColor; - selectionColor = selectionTheme.selectionColor ?? cupertinoTheme.primaryColor.withOpacity(0.40); + selectionColor = selectionTheme.selectionColor ?? + cupertinoTheme.primaryColor.withOpacity(0.40); cursorRadius ??= const Radius.circular(2); - cursorOffset = Offset(iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + cursorOffset = Offset( + iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); } else { textSelectionControls = materialTextSelectionControls; paintCursorAboveText = false; cursorOpacityAnimates = false; cursorColor ??= selectionTheme.cursorColor ?? theme.colorScheme.primary; - selectionColor = selectionTheme.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40); + selectionColor = selectionTheme.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); } - final showSelectionToolbar = - configurations.enableInteractiveSelection && configurations.enableSelectionToolbar; + final showSelectionToolbar = configurations.enableInteractiveSelection && + configurations.enableSelectionToolbar; - final placeholderBuilder = widget.configurations.placeholderComponentsConfiguration == null - ? null - : PlaceholderBuilder(configuration: widget.configurations.placeholderComponentsConfiguration!); + final placeholderBuilder = + widget.configurations.placeholderComponentsConfiguration == null + ? null + : PlaceholderBuilder( + configuration: + widget.configurations.placeholderComponentsConfiguration!); final child = FlutterQuillLocalizationsWidget( child: QuillEditorProvider( @@ -275,11 +303,14 @@ class QuillEditorState extends State implements EditorTextSelection key: _editorKey, controller: controller, configurations: QuillRawEditorConfigurations( - cursorParagrahPlaceholderConfiguration: widget.configurations.cursorParagrahPlaceholderConfiguration, + cursorParagrahPlaceholderConfiguration: + widget.configurations.cursorParagrahPlaceholderConfiguration, placeholderBuilder: placeholderBuilder, - characterShortcutEvents: widget.configurations.characterShortcutEvents, + characterShortcutEvents: + widget.configurations.characterShortcutEvents, spaceShortcutEvents: widget.configurations.spaceShortcutEvents, - customLeadingBuilder: widget.configurations.customLeadingBlockBuilder, + customLeadingBuilder: + widget.configurations.customLeadingBlockBuilder, focusNode: widget.focusNode, scrollController: widget.scrollController, scrollable: configurations.scrollable, @@ -292,7 +323,8 @@ class QuillEditorState extends State implements EditorTextSelection placeholder: configurations.placeholder, onLaunchUrl: configurations.onLaunchUrl, contextMenuBuilder: showSelectionToolbar - ? (configurations.contextMenuBuilder ?? QuillRawEditorConfigurations.defaultContextMenuBuilder) + ? (configurations.contextMenuBuilder ?? + QuillRawEditorConfigurations.defaultContextMenuBuilder) : null, showSelectionHandles: isMobile, showCursor: configurations.showCursor ?? true, @@ -302,7 +334,8 @@ class QuillEditorState extends State implements EditorTextSelection width: 2, radius: cursorRadius, offset: cursorOffset, - paintAboveText: configurations.paintCursorAboveText ?? paintCursorAboveText, + paintAboveText: + configurations.paintCursorAboveText ?? paintCursorAboveText, opacityAnimates: cursorOpacityAnimates, ), textCapitalization: configurations.textCapitalization, @@ -313,9 +346,11 @@ class QuillEditorState extends State implements EditorTextSelection expands: configurations.expands, autoFocus: configurations.autoFocus, selectionColor: selectionColor, - selectionCtrls: configurations.textSelectionControls ?? textSelectionControls, + selectionCtrls: + configurations.textSelectionControls ?? textSelectionControls, keyboardAppearance: configurations.keyboardAppearance, - enableInteractiveSelection: configurations.enableInteractiveSelection, + enableInteractiveSelection: + configurations.enableInteractiveSelection, scrollPhysics: configurations.scrollPhysics, embedBuilder: _getEmbedBuilder, linkActionPickerDelegate: configurations.linkActionPickerDelegate, @@ -330,7 +365,8 @@ class QuillEditorState extends State implements EditorTextSelection isOnTapOutsideEnabled: configurations.isOnTapOutsideEnabled, onTapOutside: configurations.onTapOutside, dialogTheme: configurations.dialogTheme, - contentInsertionConfiguration: configurations.contentInsertionConfiguration, + contentInsertionConfiguration: + configurations.contentInsertionConfiguration, enableScribble: configurations.enableScribble, onScribbleActivated: configurations.onScribbleActivated, scribbleAreaInsets: configurations.scribbleAreaInsets, @@ -413,8 +449,10 @@ class QuillEditorState extends State implements EditorTextSelection } } -class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGestureDetectorBuilder { - _QuillEditorSelectionGestureDetectorBuilder(this._state, this._detectWordBoundary) +class _QuillEditorSelectionGestureDetectorBuilder + extends EditorTextSelectionGestureDetectorBuilder { + _QuillEditorSelectionGestureDetectorBuilder( + this._state, this._detectWordBoundary) : super(delegate: _state, detectWordBoundary: _detectWordBoundary); final QuillEditorState _state; @@ -466,7 +504,8 @@ class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGes return false; } final pos = renderEditor!.getPositionForOffset(details.globalPosition); - final result = editor!.widget.controller.document.querySegmentLeafNode(pos.offset); + final result = + editor!.widget.controller.document.querySegmentLeafNode(pos.offset); final line = result.line; if (line == null) { return false; @@ -499,7 +538,8 @@ class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGes bool isShiftClick(PointerDeviceKind deviceKind) { final pressed = HardwareKeyboard.instance.logicalKeysPressed; return deviceKind == PointerDeviceKind.mouse && - (pressed.contains(LogicalKeyboardKey.shiftLeft) || pressed.contains(LogicalKeyboardKey.shiftRight)); + (pressed.contains(LogicalKeyboardKey.shiftLeft) || + pressed.contains(LogicalKeyboardKey.shiftRight)); } @override @@ -528,7 +568,8 @@ class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGes // extend current selection instead. if (isShiftClick(details.kind)) { renderEditor! - ..extendSelection(details.globalPosition, cause: SelectionChangedCause.tap) + ..extendSelection(details.globalPosition, + cause: SelectionChangedCause.tap) ..onSelectionCompleted(); } else { renderEditor! @@ -636,7 +677,8 @@ class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGes /// (including the cursor location). /// /// Used by [RenderEditor.onSelectionChanged]. -typedef TextSelectionChangedHandler = void Function(TextSelection selection, SelectionChangedCause cause); +typedef TextSelectionChangedHandler = void Function( + TextSelection selection, SelectionChangedCause cause); /// Signature for the callback that reports when a selection action is actually /// completed and ratified. Completion is defined as when the user input has @@ -655,7 +697,8 @@ const EdgeInsets _kFloatingCursorAddedMargin = EdgeInsets.fromLTRB(4, 4, 4, 5); // The additional size on the x and y axis with which to expand the prototype // cursor to render the floating cursor in pixels. -const EdgeInsets _kFloatingCaretSizeIncrease = EdgeInsets.symmetric(horizontal: 0.5, vertical: 1); +const EdgeInsets _kFloatingCaretSizeIncrease = + EdgeInsets.symmetric(horizontal: 0.5, vertical: 1); /// Displays a document as a vertical list of document segments (lines /// and blocks). @@ -680,7 +723,8 @@ class RenderEditor extends RenderEditableContainerBox required this.floatingCursorDisabled, ViewportOffset? offset, super.children, - EdgeInsets floatingCursorAddedMargin = const EdgeInsets.fromLTRB(4, 4, 4, 5), + EdgeInsets floatingCursorAddedMargin = + const EdgeInsets.fromLTRB(4, 4, 4, 5), double? maxContentWidth, }) : _hasFocus = hasFocus, _extendSelectionOrigin = selection, @@ -706,16 +750,19 @@ class RenderEditor extends RenderEditableContainerBox /// Called when the selection changes. TextSelectionChangedHandler onSelectionChanged; TextSelectionCompletedHandler onSelectionCompleted; - final ValueNotifier _selectionStartInViewport = ValueNotifier(true); + final ValueNotifier _selectionStartInViewport = + ValueNotifier(true); - ValueListenable get selectionStartInViewport => _selectionStartInViewport; + ValueListenable get selectionStartInViewport => + _selectionStartInViewport; ValueListenable get selectionEndInViewport => _selectionEndInViewport; final ValueNotifier _selectionEndInViewport = ValueNotifier(true); void _updateSelectionExtentsVisibility(Offset effectiveOffset) { final visibleRegion = Offset.zero & size; - final startPosition = TextPosition(offset: selection.start, affinity: selection.affinity); + final startPosition = + TextPosition(offset: selection.start, affinity: selection.affinity); final startOffset = _getOffsetForCaret(startPosition); // TODO(justinmc): https://github.com/flutter/flutter/issues/31495 // Check if the selection is visible with an approximation because a @@ -725,12 +772,16 @@ class RenderEditor extends RenderEditableContainerBox // _applyFloatingPointHack. Ideally, the rounding mismatch will be fixed and // this can be changed to be a strict check instead of an approximation. const visibleRegionSlop = 0.5; - _selectionStartInViewport.value = - visibleRegion.inflate(visibleRegionSlop).contains(startOffset + effectiveOffset); + _selectionStartInViewport.value = visibleRegion + .inflate(visibleRegionSlop) + .contains(startOffset + effectiveOffset); - final endPosition = TextPosition(offset: selection.end, affinity: selection.affinity); + final endPosition = + TextPosition(offset: selection.end, affinity: selection.affinity); final endOffset = _getOffsetForCaret(endPosition); - _selectionEndInViewport.value = visibleRegion.inflate(visibleRegionSlop).contains(endOffset + effectiveOffset); + _selectionEndInViewport.value = visibleRegion + .inflate(visibleRegionSlop) + .contains(endOffset + effectiveOffset); } // returns offset relative to this at which the caret will be painted @@ -787,8 +838,10 @@ class RenderEditor extends RenderEditableContainerBox } bool get _shiftPressed => - HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.shiftLeft) || - HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.shiftRight); + HardwareKeyboard.instance.logicalKeysPressed + .contains(LogicalKeyboardKey.shiftLeft) || + HardwareKeyboard.instance.logicalKeysPressed + .contains(LogicalKeyboardKey.shiftRight); void setStartHandleLayerLink(LayerLink value) { if (_startHandleLayerLink == value) { @@ -823,7 +876,8 @@ class RenderEditor extends RenderEditableContainerBox } @override - List getEndpointsForSelection(TextSelection textSelection) { + List getEndpointsForSelection( + TextSelection textSelection) { if (textSelection.isCollapsed) { final child = childAtPosition(textSelection.extent); final localPosition = TextPosition( @@ -834,7 +888,10 @@ class RenderEditor extends RenderEditableContainerBox final parentData = child.parentData as BoxParentData; return [ TextSelectionPoint( - Offset(0, child.preferredLineHeight(localPosition)) + localOffset + parentData.offset, null) + Offset(0, child.preferredLineHeight(localPosition)) + + localOffset + + parentData.offset, + null) ]; } @@ -850,7 +907,8 @@ class RenderEditor extends RenderEditableContainerBox assert(baseChild != null); final baseParentData = baseChild!.parentData as BoxParentData; - final baseSelection = localSelection(baseChild.container, textSelection, true); + final baseSelection = + localSelection(baseChild.container, textSelection, true); var basePoint = baseChild.getBaseEndpointForSelection(baseSelection); basePoint = TextSelectionPoint( basePoint.point + baseParentData.offset, @@ -879,8 +937,10 @@ class RenderEditor extends RenderEditableContainerBox assert(extentChild != null); final extentParentData = extentChild!.parentData as BoxParentData; - final extentSelection = localSelection(extentChild.container, textSelection, true); - var extentPoint = extentChild.getExtentEndpointForSelection(extentSelection); + final extentSelection = + localSelection(extentChild.container, textSelection, true); + var extentPoint = + extentChild.getExtentEndpointForSelection(extentSelection); extentPoint = TextSelectionPoint( extentPoint.point + extentParentData.offset, extentPoint.direction, @@ -937,7 +997,8 @@ class RenderEditor extends RenderEditableContainerBox ) { final firstPosition = getPositionForOffset(from); final firstWord = selectWordAtPosition(firstPosition); - final lastWord = to == null ? firstWord : selectWordAtPosition(getPositionForOffset(to)); + final lastWord = + to == null ? firstWord : selectWordAtPosition(getPositionForOffset(to)); _handleSelectionChange( TextSelection( @@ -953,8 +1014,12 @@ class RenderEditor extends RenderEditableContainerBox TextSelection nextSelection, SelectionChangedCause cause, ) { - final focusingEmpty = nextSelection.baseOffset == 0 && nextSelection.extentOffset == 0 && !_hasFocus; - if (nextSelection == selection && cause != SelectionChangedCause.keyboard && !focusingEmpty) { + final focusingEmpty = nextSelection.baseOffset == 0 && + nextSelection.extentOffset == 0 && + !_hasFocus; + if (nextSelection == selection && + cause != SelectionChangedCause.keyboard && + !focusingEmpty) { return; } onSelectionChanged(nextSelection, cause); @@ -1005,7 +1070,8 @@ class RenderEditor extends RenderEditableContainerBox ); // Don't change selection if the selected word is a placeholder. - if (child.container.style.attributes.containsKey(Attribute.placeholder.key)) { + if (child.container.style.attributes + .containsKey(Attribute.placeholder.key)) { return; } @@ -1016,7 +1082,8 @@ class RenderEditor extends RenderEditableContainerBox ); } else { _handleSelectionChange( - TextSelection.collapsed(offset: word.end, affinity: TextAffinity.upstream), + TextSelection.collapsed( + offset: word.end, affinity: TextAffinity.upstream), cause, ); } @@ -1091,7 +1158,8 @@ class RenderEditor extends RenderEditableContainerBox ' resize its children, so it must be ' 'placed in a parent that does not constrain the main ' 'axis.'), - ErrorHint('You probably want to put the RenderEditableContainerBox inside a ' + ErrorHint( + 'You probably want to put the RenderEditableContainerBox inside a ' 'RenderViewport with a matching main axis or disable the ' 'scrollable property.') ]); @@ -1113,11 +1181,13 @@ class RenderEditor extends RenderEditableContainerBox var mainAxisExtent = resolvedPadding!.top; var child = firstChild; - final innerConstraints = - BoxConstraints.tightFor(width: math.min(_maxContentWidth ?? double.infinity, constraints.maxWidth)) - .deflate(resolvedPadding!); - final leftOffset = - _maxContentWidth == null ? 0.0 : math.max((constraints.maxWidth - _maxContentWidth!) / 2, 0); + final innerConstraints = BoxConstraints.tightFor( + width: math.min( + _maxContentWidth ?? double.infinity, constraints.maxWidth)) + .deflate(resolvedPadding!); + final leftOffset = _maxContentWidth == null + ? 0.0 + : math.max((constraints.maxWidth - _maxContentWidth!) / 2, 0); while (child != null) { child.layout(innerConstraints, parentUsesSize: true); final childParentData = child.parentData as EditableContainerParentData @@ -1134,14 +1204,18 @@ class RenderEditor extends RenderEditableContainerBox @override void paint(PaintingContext context, Offset offset) { - if (_hasFocus && _cursorController.show.value && !_cursorController.style.paintAboveText) { + if (_hasFocus && + _cursorController.show.value && + !_cursorController.style.paintAboveText) { _paintFloatingCursor(context, offset); } defaultPaint(context, offset); _updateSelectionExtentsVisibility(offset + _paintOffset); _paintHandleLayers(context, getEndpointsForSelection(selection)); - if (_hasFocus && _cursorController.show.value && _cursorController.style.paintAboveText) { + if (_hasFocus && + _cursorController.show.value && + _cursorController.style.paintAboveText) { _paintFloatingCursor(context, offset); } } @@ -1151,7 +1225,8 @@ class RenderEditor extends RenderEditableContainerBox return defaultHitTestChildren(result, position: position); } - void _paintHandleLayers(PaintingContext context, List endpoints) { + void _paintHandleLayers( + PaintingContext context, List endpoints) { var startPoint = endpoints[0].point; startPoint = Offset( startPoint.dx.clamp(0.0, size.width), @@ -1179,7 +1254,8 @@ class RenderEditor extends RenderEditableContainerBox @override double preferredLineHeight(TextPosition position) { final child = childAtPosition(position); - return child.preferredLineHeight(TextPosition(offset: position.offset - child.container.offset)); + return child.preferredLineHeight( + TextPosition(offset: position.offset - child.container.offset)); } @override @@ -1214,7 +1290,8 @@ class RenderEditor extends RenderEditableContainerBox /// this editor from above it. /// /// Returns `null` if the cursor is currently visible. - double? getOffsetToRevealCursor(double viewportHeight, double scrollOffset, double offsetInViewport) { + double? getOffsetToRevealCursor( + double viewportHeight, double scrollOffset, double offsetInViewport) { // Endpoints coordinates represents lower left or lower right corner of // the selection. If we want to scroll up to reveal the caret we need to // adjust the dy value by the height of the line. We also add a small margin @@ -1227,7 +1304,9 @@ class RenderEditor extends RenderEditableContainerBox endpoint = endpoints.first; } else { if (selection is DragTextSelection) { - endpoint = (selection as DragTextSelection).first ? endpoints.first : endpoints.last; + endpoint = (selection as DragTextSelection).first + ? endpoints.first + : endpoints.last; } else { endpoint = endpoints.first; } @@ -1238,11 +1317,13 @@ class RenderEditor extends RenderEditableContainerBox const kMargin = 8.0; final caretTop = endpoint.point.dy - - child.preferredLineHeight(TextPosition(offset: selection.extentOffset - child.container.documentOffset)) - + child.preferredLineHeight(TextPosition( + offset: selection.extentOffset - child.container.documentOffset)) - kMargin + offsetInViewport + scrollBottomInset; - final caretBottom = endpoint.point.dy + kMargin + offsetInViewport + scrollBottomInset; + final caretBottom = + endpoint.point.dy + kMargin + offsetInViewport + scrollBottomInset; double? dy; if (caretTop < scrollOffset) { dy = caretTop; @@ -1292,10 +1373,12 @@ class RenderEditor extends RenderEditableContainerBox bool _resetOriginOnBottom = false; /// Returns the position within the editor closest to the raw cursor offset. - Offset calculateBoundedFloatingCursorOffset(Offset rawCursorOffset, double preferredLineHeight) { + Offset calculateBoundedFloatingCursorOffset( + Offset rawCursorOffset, double preferredLineHeight) { var deltaPosition = Offset.zero; final topBound = _kFloatingCursorAddedMargin.top; - final bottomBound = size.height - preferredLineHeight + _kFloatingCursorAddedMargin.bottom; + final bottomBound = + size.height - preferredLineHeight + _kFloatingCursorAddedMargin.bottom; final leftBound = _kFloatingCursorAddedMargin.left; final rightBound = size.width - _kFloatingCursorAddedMargin.right; @@ -1307,24 +1390,30 @@ class RenderEditor extends RenderEditableContainerBox // we want to reset the relative origin of // the dragging when the user drags back into the field. if (_resetOriginOnLeft && deltaPosition.dx > 0) { - _relativeOrigin = Offset(rawCursorOffset.dx - leftBound, _relativeOrigin.dy); + _relativeOrigin = + Offset(rawCursorOffset.dx - leftBound, _relativeOrigin.dy); _resetOriginOnLeft = false; } else if (_resetOriginOnRight && deltaPosition.dx < 0) { - _relativeOrigin = Offset(rawCursorOffset.dx - rightBound, _relativeOrigin.dy); + _relativeOrigin = + Offset(rawCursorOffset.dx - rightBound, _relativeOrigin.dy); _resetOriginOnRight = false; } if (_resetOriginOnTop && deltaPosition.dy > 0) { - _relativeOrigin = Offset(_relativeOrigin.dx, rawCursorOffset.dy - topBound); + _relativeOrigin = + Offset(_relativeOrigin.dx, rawCursorOffset.dy - topBound); _resetOriginOnTop = false; } else if (_resetOriginOnBottom && deltaPosition.dy < 0) { - _relativeOrigin = Offset(_relativeOrigin.dx, rawCursorOffset.dy - bottomBound); + _relativeOrigin = + Offset(_relativeOrigin.dx, rawCursorOffset.dy - bottomBound); _resetOriginOnBottom = false; } final currentX = rawCursorOffset.dx - _relativeOrigin.dx; final currentY = rawCursorOffset.dy - _relativeOrigin.dy; - final double adjustedX = math.min(math.max(currentX, leftBound), rightBound); - final double adjustedY = math.min(math.max(currentY, topBound), bottomBound); + final double adjustedX = + math.min(math.max(currentX, leftBound), rightBound); + final double adjustedY = + math.min(math.max(currentY, topBound), bottomBound); final adjustedOffset = Offset(adjustedX, adjustedY); if (currentX < leftBound && deltaPosition.dx < 0) { @@ -1344,7 +1433,8 @@ class RenderEditor extends RenderEditableContainerBox } @override - void setFloatingCursor(FloatingCursorDragState dragState, Offset boundedOffset, TextPosition textPosition, + void setFloatingCursor(FloatingCursorDragState dragState, + Offset boundedOffset, TextPosition textPosition, {double? resetLerpValue}) { if (floatingCursorDisabled) return; @@ -1360,13 +1450,17 @@ class RenderEditor extends RenderEditableContainerBox if (_floatingCursorOn) { _floatingCursorTextPosition = textPosition; final sizeAdjustment = resetLerpValue != null - ? EdgeInsets.lerp(_kFloatingCaretSizeIncrease, EdgeInsets.zero, resetLerpValue)! + ? EdgeInsets.lerp( + _kFloatingCaretSizeIncrease, EdgeInsets.zero, resetLerpValue)! : _kFloatingCaretSizeIncrease; final child = childAtPosition(textPosition); - final caretPrototype = child.getCaretPrototype(child.globalToLocalPosition(textPosition)); - _floatingCursorRect = sizeAdjustment.inflateRect(caretPrototype).shift(boundedOffset); + final caretPrototype = + child.getCaretPrototype(child.globalToLocalPosition(textPosition)); + _floatingCursorRect = + sizeAdjustment.inflateRect(caretPrototype).shift(boundedOffset); - _cursorController.setFloatingCursorTextPosition(_floatingCursorTextPosition); + _cursorController + .setFloatingCursorTextPosition(_floatingCursorTextPosition); } else { _floatingCursorRect = null; _cursorController.setFloatingCursorTextPosition(null); @@ -1387,7 +1481,8 @@ class RenderEditor extends RenderEditableContainerBox TextSelection getLineAtOffset(TextPosition position) { final child = childAtPosition(position); final nodeOffset = child.container.offset; - final localPosition = TextPosition(offset: position.offset - nodeOffset, affinity: position.affinity); + final localPosition = TextPosition( + offset: position.offset - nodeOffset, affinity: position.affinity); final localLineRange = child.getLineBoundary(localPosition); final line = TextRange( start: localLineRange.start + nodeOffset, @@ -1400,7 +1495,8 @@ class RenderEditor extends RenderEditableContainerBox TextRange getWordBoundary(TextPosition position) { final child = childAtPosition(position); final nodeOffset = child.container.offset; - final localPosition = TextPosition(offset: position.offset - nodeOffset, affinity: position.affinity); + final localPosition = TextPosition( + offset: position.offset - nodeOffset, affinity: position.affinity); final localWord = child.getWordBoundary(localPosition); return TextRange( start: localWord.start + nodeOffset, @@ -1409,7 +1505,8 @@ class RenderEditor extends RenderEditableContainerBox } /// Returns the TextPosition after moving by the vertical offset. - TextPosition getTextPositionMoveVertical(TextPosition position, double verticalOffset) { + TextPosition getTextPositionMoveVertical( + TextPosition position, double verticalOffset) { final caretOfs = localToGlobal(_getOffsetForCaret(position)); return getPositionForOffset(caretOfs.translate(0, verticalOffset)); } @@ -1421,7 +1518,8 @@ class RenderEditor extends RenderEditableContainerBox @override TextPosition getTextPositionAbove(TextPosition position) { final child = childAtPosition(position); - final localPosition = TextPosition(offset: position.offset - child.container.documentOffset); + final localPosition = + TextPosition(offset: position.offset - child.container.documentOffset); var newPosition = child.getPositionAbove(localPosition); @@ -1439,10 +1537,12 @@ class RenderEditor extends RenderEditableContainerBox final testOffset = sibling.getOffsetForCaret(testPosition); final finalOffset = Offset(caretOffset.dx, testOffset.dy); final siblingPosition = sibling.getPositionForOffset(finalOffset); - newPosition = TextPosition(offset: sibling.container.documentOffset + siblingPosition.offset); + newPosition = TextPosition( + offset: sibling.container.documentOffset + siblingPosition.offset); } } else { - newPosition = TextPosition(offset: child.container.documentOffset + newPosition.offset); + newPosition = TextPosition( + offset: child.container.documentOffset + newPosition.offset); } return newPosition; } @@ -1487,7 +1587,8 @@ class RenderEditor extends RenderEditableContainerBox // End TextLayoutMetrics implementation - QuillVerticalCaretMovementRun startVerticalCaretMovement(TextPosition startPosition) { + QuillVerticalCaretMovementRun startVerticalCaretMovement( + TextPosition startPosition) { return QuillVerticalCaretMovementRun._( this, startPosition, @@ -1528,19 +1629,23 @@ class QuillVerticalCaretMovementRun implements Iterator { } void moveVertical(double verticalOffset) { - _currentTextPosition = _editor.getTextPositionMoveVertical(_currentTextPosition, verticalOffset); + _currentTextPosition = _editor.getTextPositionMoveVertical( + _currentTextPosition, verticalOffset); } } -class EditableContainerParentData extends ContainerBoxParentData {} +class EditableContainerParentData + extends ContainerBoxParentData {} /// Multi-child render box of editable content. /// /// Common ancestor for [RenderEditor] and [RenderEditableTextBlock]. class RenderEditableContainerBox extends RenderBox with - ContainerRenderObjectMixin, - RenderBoxContainerDefaultsMixin { + ContainerRenderObjectMixin, + RenderBoxContainerDefaultsMixin { RenderEditableContainerBox({ required container_node.QuillContainer container, required this.textDirection, @@ -1669,7 +1774,9 @@ class RenderEditableContainerBox extends RenderBox var mainAxisExtent = _resolvedPadding!.top; var child = firstChild; - final innerConstraints = BoxConstraints.tightFor(width: constraints.maxWidth).deflate(_resolvedPadding!); + final innerConstraints = + BoxConstraints.tightFor(width: constraints.maxWidth) + .deflate(_resolvedPadding!); while (child != null) { child.layout(innerConstraints, parentUsesSize: true); final childParentData = (child.parentData as EditableContainerParentData) @@ -1710,8 +1817,11 @@ class RenderEditableContainerBox extends RenderBox double computeMinIntrinsicWidth(double height) { resolvePadding(); return _getIntrinsicCrossAxis((child) { - final childHeight = math.max(0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); - return child.getMinIntrinsicWidth(childHeight) + _resolvedPadding!.left + _resolvedPadding!.right; + final childHeight = math.max( + 0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); + return child.getMinIntrinsicWidth(childHeight) + + _resolvedPadding!.left + + _resolvedPadding!.right; }); } @@ -1719,8 +1829,11 @@ class RenderEditableContainerBox extends RenderBox double computeMaxIntrinsicWidth(double height) { resolvePadding(); return _getIntrinsicCrossAxis((child) { - final childHeight = math.max(0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); - return child.getMaxIntrinsicWidth(childHeight) + _resolvedPadding!.left + _resolvedPadding!.right; + final childHeight = math.max( + 0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); + return child.getMaxIntrinsicWidth(childHeight) + + _resolvedPadding!.left + + _resolvedPadding!.right; }); } @@ -1728,8 +1841,11 @@ class RenderEditableContainerBox extends RenderBox double computeMinIntrinsicHeight(double width) { resolvePadding(); return _getIntrinsicMainAxis((child) { - final childWidth = math.max(0, width - _resolvedPadding!.left + _resolvedPadding!.right); - return child.getMinIntrinsicHeight(childWidth) + _resolvedPadding!.top + _resolvedPadding!.bottom; + final childWidth = math.max( + 0, width - _resolvedPadding!.left + _resolvedPadding!.right); + return child.getMinIntrinsicHeight(childWidth) + + _resolvedPadding!.top + + _resolvedPadding!.bottom; }); } @@ -1737,14 +1853,18 @@ class RenderEditableContainerBox extends RenderBox double computeMaxIntrinsicHeight(double width) { resolvePadding(); return _getIntrinsicMainAxis((child) { - final childWidth = math.max(0, width - _resolvedPadding!.left + _resolvedPadding!.right); - return child.getMaxIntrinsicHeight(childWidth) + _resolvedPadding!.top + _resolvedPadding!.bottom; + final childWidth = math.max( + 0, width - _resolvedPadding!.left + _resolvedPadding!.right); + return child.getMaxIntrinsicHeight(childWidth) + + _resolvedPadding!.top + + _resolvedPadding!.bottom; }); } @override double computeDistanceToActualBaseline(TextBaseline baseline) { resolvePadding(); - return defaultComputeDistanceToFirstActualBaseline(baseline)! + _resolvedPadding!.top; + return defaultComputeDistanceToFirstActualBaseline(baseline)! + + _resolvedPadding!.top; } } diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 34fa7bde7..157b716b5 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -1,6 +1,14 @@ // This file is only for internal use import 'package:flutter/material.dart' - show Expanded, Row, Text, TextDirection, TextStyle, TextWidthBasis, Widget, immutable; + show + Expanded, + Row, + Text, + TextDirection, + TextStyle, + TextWidthBasis, + Widget, + immutable; import 'package:meta/meta.dart'; import '../../../../document/attribute.dart' show Attribute, AttributeScope; import '../../../../document/nodes/line.dart'; @@ -26,8 +34,10 @@ class PlaceholderBuilder { final PlaceholderComponentsConfiguration configuration; - Map get builders => configuration.builders; - Set? get customBlockAttributesKeys => configuration.customBlockAttributesKeys; + Map get builders => + configuration.builders; + Set? get customBlockAttributesKeys => + configuration.customBlockAttributesKeys; /// Check if this node need to show a placeholder @experimental @@ -35,7 +45,10 @@ class PlaceholderBuilder { if (builders.isEmpty || _validateCombinableStyles(node)) return (false, ''); var shouldShow = false; var key = ''; - for (final exclusiveKey in {...Attribute.exclusiveBlockKeys, ...?customBlockAttributesKeys}) { + for (final exclusiveKey in { + ...Attribute.exclusiveBlockKeys, + ...?customBlockAttributesKeys + }) { if (node.style.containsKey(exclusiveKey) && node.style.attributes[exclusiveKey]?.scope == AttributeScope.block && !_blackList.contains(exclusiveKey)) { @@ -49,7 +62,7 @@ class PlaceholderBuilder { return (node.isEmpty && shouldShow, key); } - /// We use this to validate if the node contains + /// We use this to validate if the node contains /// styles that can be combined with other block styles @experimental bool _validateCombinableStyles(Line node) { @@ -72,7 +85,8 @@ class PlaceholderBuilder { required TextDirection textDirection, }) { if (builders.isEmpty) return null; - final configuration = builders[blockAttribute.key]?.call(blockAttribute, lineStyle); + final configuration = + builders[blockAttribute.key]?.call(blockAttribute, lineStyle); // we return a row because this widget takes the whole width and makes possible // select the block correctly (without this the block line cannot be selected correctly) return configuration == null || configuration.placeholderText.trim().isEmpty diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 0c240c735..5da98beae 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -270,27 +270,29 @@ class _TextLineState extends State { TextStyle lineStyle, ) { var addWebNodeIfNeeded = widget.placeholderBuilder == null; - if (widget.placeholderBuilder != null && nodes.isEmpty && widget.placeholderBuilder!.builders.isNotEmpty) { - final (shouldShowNode, attrKey) = - widget.placeholderBuilder!.shouldShowPlaceholder(widget.line); - if (shouldShowNode) { - final style = _getInlineTextStyle( - const Style(), defaultStyles, widget.line.style, false); - final placeholderWidget = widget.placeholderBuilder!.build( - blockAttribute: widget.line.style.attributes[attrKey]!, - lineStyle: lineStyle.merge(style), - textDirection: widget.textDirection ?? Directionality.of(context), - ); - if (placeholderWidget != null) { - final widgetSpan = _getTextSpanFromNode( - defaultStyles, - leaf.QuillText(''), - widget.line.style, - placeholderWidget: placeholderWidget, + if (widget.placeholderBuilder != null && + nodes.isEmpty && + widget.placeholderBuilder!.builders.isNotEmpty) { + final (shouldShowNode, attrKey) = + widget.placeholderBuilder!.shouldShowPlaceholder(widget.line); + if (shouldShowNode) { + final style = _getInlineTextStyle( + const Style(), defaultStyles, widget.line.style, false); + final placeholderWidget = widget.placeholderBuilder!.build( + blockAttribute: widget.line.style.attributes[attrKey]!, + lineStyle: lineStyle.merge(style), + textDirection: widget.textDirection ?? Directionality.of(context), ); - return TextSpan(children: [widgetSpan], style: lineStyle); + if (placeholderWidget != null) { + final widgetSpan = _getTextSpanFromNode( + defaultStyles, + leaf.QuillText(''), + widget.line.style, + placeholderWidget: placeholderWidget, + ); + return TextSpan(children: [widgetSpan], style: lineStyle); + } } - } // if the [placeholderWidget] is null or [shouldShowNode] is false // then this line will be executed and avoid non add // the needed node when the line is empty From aa131a41e7e5557f3f0e880124a8485726004f9d Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 19 Sep 2024 20:31:25 -0400 Subject: [PATCH 021/113] Chore: revert change where the placeholder is hiden if node contains indent or align --- .../placeholder_builder_internal.dart | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 157b716b5..22466a2a8 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -26,6 +26,7 @@ late final List _blackList = List.unmodifiable([ ...Attribute.ignoreKeys, ]); +@experimental @immutable class PlaceholderBuilder { const PlaceholderBuilder({ @@ -42,7 +43,7 @@ class PlaceholderBuilder { /// Check if this node need to show a placeholder @experimental (bool, String) shouldShowPlaceholder(Line node) { - if (builders.isEmpty || _validateCombinableStyles(node)) return (false, ''); + if (builders.isEmpty) return (false, ''); var shouldShow = false; var key = ''; for (final exclusiveKey in { @@ -62,22 +63,6 @@ class PlaceholderBuilder { return (node.isEmpty && shouldShow, key); } - /// We use this to validate if the node contains - /// styles that can be combined with other block styles - @experimental - bool _validateCombinableStyles(Line node) { - for (final exclusiveKey in [ - Attribute.indent.key, - Attribute.align.key, - Attribute.lineHeight.key, - ]) { - if (node.style.containsKey(exclusiveKey)) { - return true; - } - } - return false; - } - @experimental Widget? build({ required Attribute blockAttribute, From f2db22b0061b3a9bf540bd0513bd396983611375 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 19 Sep 2024 23:14:38 -0400 Subject: [PATCH 022/113] Fix: placeholder does not show the aligned applied in the line --- .../placeholder_builder_internal.dart | 74 +++++++++++++------ lib/src/editor/widgets/text/text_line.dart | 26 ++----- 2 files changed, 60 insertions(+), 40 deletions(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 22466a2a8..cbcdf325c 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -1,13 +1,20 @@ // This file is only for internal use import 'package:flutter/material.dart' show + Align, + Alignment, + CrossAxisAlignment, Expanded, + MainAxisAlignment, Row, + StrutStyle, Text, + TextAlign, + TextBaseline, TextDirection, TextStyle, TextWidthBasis, - Widget, + WidgetSpan, immutable; import 'package:meta/meta.dart'; import '../../../../document/attribute.dart' show Attribute, AttributeScope; @@ -26,7 +33,7 @@ late final List _blackList = List.unmodifiable([ ...Attribute.ignoreKeys, ]); -@experimental +@experimental @immutable class PlaceholderBuilder { const PlaceholderBuilder({ @@ -63,33 +70,56 @@ class PlaceholderBuilder { return (node.isEmpty && shouldShow, key); } + /// Build is similar to build method from any widget but + /// this only has the responsability of create a WidgetSpan to be showed + /// by the line when the node is empty + /// + /// Before use this, we should always use [shouldShowPlaceholder] to avoid + /// show any placeholder where is not needed @experimental - Widget? build({ + WidgetSpan? build({ required Attribute blockAttribute, required TextStyle lineStyle, required TextDirection textDirection, + required StrutStyle strutStyle, + required TextAlign align, }) { if (builders.isEmpty) return null; final configuration = builders[blockAttribute.key]?.call(blockAttribute, lineStyle); - // we return a row because this widget takes the whole width and makes possible - // select the block correctly (without this the block line cannot be selected correctly) - return configuration == null || configuration.placeholderText.trim().isEmpty - ? null - : Row( - children: [ - // expanded let us add text as large as possible without breaks - // the horizontal view - Expanded( - child: Text( - configuration.placeholderText, - style: configuration.style, - textDirection: textDirection, - softWrap: true, - textWidthBasis: TextWidthBasis.longestLine, - ), - ), - ], - ); + // we don't need to add a placeholder that is null or contains a empty text + if (configuration == null || configuration.placeholderText.trim().isEmpty) + return null; + final textWidget = Text( + configuration.placeholderText, + style: configuration.style, + textDirection: textDirection, + softWrap: true, + strutStyle: strutStyle, + textAlign: align, + textWidthBasis: TextWidthBasis.longestLine, + ); + // we use [Align] widget to take whole the available width + // when the line has not defined an alignment. + // + // this behavior is different when the align is left or justify, because + // if we align to the center (example) the line, align as we say, will take the whole + // width, creating a visual unexpected behavior where the caret being putted + // at the offset 0 (you can think this like the caret appears at the first char + // of the line when it is aligned at the left side instead appears at the middle + // if the line is centered) + // + // # !Note: + // this code is subject to changes because we need to get a better solution + // to this implementation + return WidgetSpan( + style: lineStyle, + child: align != TextAlign.left && align != TextAlign.justify + ? textWidget + : Align( + alignment: Alignment.centerLeft, + child: textWidget, + ), + ); } } diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 5da98beae..12bf8610f 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -276,21 +276,17 @@ class _TextLineState extends State { final (shouldShowNode, attrKey) = widget.placeholderBuilder!.shouldShowPlaceholder(widget.line); if (shouldShowNode) { - final style = _getInlineTextStyle( - const Style(), defaultStyles, widget.line.style, false); + final style = lineStyle.merge(_getInlineTextStyle( + const Style(), defaultStyles, widget.line.style, false)); final placeholderWidget = widget.placeholderBuilder!.build( blockAttribute: widget.line.style.attributes[attrKey]!, - lineStyle: lineStyle.merge(style), + lineStyle: style, textDirection: widget.textDirection ?? Directionality.of(context), + align: _getTextAlign(), + strutStyle: StrutStyle.fromTextStyle(style), ); if (placeholderWidget != null) { - final widgetSpan = _getTextSpanFromNode( - defaultStyles, - leaf.QuillText(''), - widget.line.style, - placeholderWidget: placeholderWidget, - ); - return TextSpan(children: [widgetSpan], style: lineStyle); + return TextSpan(children: [placeholderWidget], style: lineStyle); } } // if the [placeholderWidget] is null or [shouldShowNode] is false @@ -491,17 +487,14 @@ class _TextLineState extends State { } InlineSpan _getTextSpanFromNode( - DefaultStyles defaultStyles, - Node node, - Style lineStyle, { - Widget? placeholderWidget, - }) { + DefaultStyles defaultStyles, Node node, Style lineStyle) { final textNode = node as leaf.QuillText; final nodeStyle = textNode.style; final isLink = nodeStyle.containsKey(Attribute.link.key) && nodeStyle.attributes[Attribute.link.key]!.value != null; final style = _getInlineTextStyle(nodeStyle, defaultStyles, lineStyle, isLink); + if (widget.controller.configurations.requireScriptFontFeatures == false && textNode.value.isNotEmpty) { if (nodeStyle.containsKey(Attribute.script.key)) { @@ -512,9 +505,6 @@ class _TextLineState extends State { } } } - if (placeholderWidget != null) { - return WidgetSpan(child: placeholderWidget, style: style); - } if (!isLink && !widget.readOnly && From b90f3af23633925c47af674eabb381a736512f8f Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 19 Sep 2024 23:20:30 -0400 Subject: [PATCH 023/113] Chore: removed unused imports --- .../builders/placeholder/placeholder_builder_internal.dart | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index cbcdf325c..c10a470ec 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -3,14 +3,9 @@ import 'package:flutter/material.dart' show Align, Alignment, - CrossAxisAlignment, - Expanded, - MainAxisAlignment, - Row, StrutStyle, Text, TextAlign, - TextBaseline, TextDirection, TextStyle, TextWidthBasis, From 2fb3131ab72795462ece815f1df55fd144e3fccb Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 19 Sep 2024 23:33:35 -0400 Subject: [PATCH 024/113] Chore: fix curly issue with flutter analysis --- .../builders/placeholder/placeholder_builder_internal.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index c10a470ec..5c3a2a8ca 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -83,8 +83,9 @@ class PlaceholderBuilder { final configuration = builders[blockAttribute.key]?.call(blockAttribute, lineStyle); // we don't need to add a placeholder that is null or contains a empty text - if (configuration == null || configuration.placeholderText.trim().isEmpty) + if (configuration == null || configuration.placeholderText.trim().isEmpty) { return null; + } final textWidget = Text( configuration.placeholderText, style: configuration.style, From e412236bdbdeca83f987b596a0bf65c71b203196 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Fri, 20 Sep 2024 15:37:33 -0400 Subject: [PATCH 025/113] Chore: add internal annotations and make strutStyle optional in build method for PlaceholderBuilder --- .../builders/placeholder/placeholder_builder_internal.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 5c3a2a8ca..5170a4d04 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -29,6 +29,7 @@ late final List _blackList = List.unmodifiable([ ]); @experimental +@internal @immutable class PlaceholderBuilder { const PlaceholderBuilder({ @@ -44,6 +45,7 @@ class PlaceholderBuilder { /// Check if this node need to show a placeholder @experimental + @internal (bool, String) shouldShowPlaceholder(Line node) { if (builders.isEmpty) return (false, ''); var shouldShow = false; @@ -72,12 +74,13 @@ class PlaceholderBuilder { /// Before use this, we should always use [shouldShowPlaceholder] to avoid /// show any placeholder where is not needed @experimental + @internal WidgetSpan? build({ required Attribute blockAttribute, required TextStyle lineStyle, required TextDirection textDirection, - required StrutStyle strutStyle, required TextAlign align, + StrutStyle? strutStyle, }) { if (builders.isEmpty) return null; final configuration = @@ -105,7 +108,7 @@ class PlaceholderBuilder { // of the line when it is aligned at the left side instead appears at the middle // if the line is centered) // - // # !Note: + // Note: // this code is subject to changes because we need to get a better solution // to this implementation return WidgetSpan( From 3f2d4e496670f96cd85ed866b89d3d3ab374715d Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Fri, 20 Sep 2024 16:12:39 -0400 Subject: [PATCH 026/113] Fix: widget span is generating unexpected behaviors with the caret --- .../placeholder_builder_internal.dart | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 5170a4d04..abf2d81d5 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -3,9 +3,15 @@ import 'package:flutter/material.dart' show Align, Alignment, + CrossAxisAlignment, + Expanded, + MainAxisAlignment, + PlaceholderAlignment, + Row, StrutStyle, Text, TextAlign, + TextBaseline, TextDirection, TextStyle, TextWidthBasis, @@ -98,11 +104,11 @@ class PlaceholderBuilder { textAlign: align, textWidthBasis: TextWidthBasis.longestLine, ); - // we use [Align] widget to take whole the available width + // we use [Row] widget with [Expanded] to take whole the available width // when the line has not defined an alignment. // // this behavior is different when the align is left or justify, because - // if we align to the center (example) the line, align as we say, will take the whole + // if we align the line to the center (example), row will take the whole // width, creating a visual unexpected behavior where the caret being putted // at the offset 0 (you can think this like the caret appears at the first char // of the line when it is aligned at the left side instead appears at the middle @@ -113,11 +119,14 @@ class PlaceholderBuilder { // to this implementation return WidgetSpan( style: lineStyle, - child: align != TextAlign.left && align != TextAlign.justify + child: align == TextAlign.end || align == TextAlign.center ? textWidget - : Align( - alignment: Alignment.centerLeft, - child: textWidget, + : Row( + children: [ + Expanded( + child: textWidget, + ), + ], ), ); } From 8556861fe1d9f24edea966cce512d5e8fd96b3a3 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Fri, 20 Sep 2024 16:14:55 -0400 Subject: [PATCH 027/113] Fix: placeholder text span is not taking the style of the dev --- lib/src/editor/widgets/text/text_line.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 12bf8610f..a686d9f2b 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -286,7 +286,7 @@ class _TextLineState extends State { strutStyle: StrutStyle.fromTextStyle(style), ); if (placeholderWidget != null) { - return TextSpan(children: [placeholderWidget], style: lineStyle); + return TextSpan(children: [placeholderWidget], style: style); } } // if the [placeholderWidget] is null or [shouldShowNode] is false From 612a36a4b3553df7960848ed95ef94fb52e85394 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 19 Sep 2024 23:36:11 +0300 Subject: [PATCH 028/113] chore(github): update the question template to add the question label to the issue report --- .github/ISSUE_TEMPLATE/3_question.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/3_question.yml b/.github/ISSUE_TEMPLATE/3_question.yml index f21caa90b..fc462fc0b 100644 --- a/.github/ISSUE_TEMPLATE/3_question.yml +++ b/.github/ISSUE_TEMPLATE/3_question.yml @@ -1,7 +1,7 @@ name: Ask a question description: | If you have any questions, feel free to ask -labels: 'help wanted' +labels: 'question' body: - type: markdown attributes: From 64116484d0dbc51dbb181dc052e8f26c1c54c782 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 20 Sep 2024 01:54:42 +0300 Subject: [PATCH 029/113] chore(github): remove 'Code sample' text area input from bug report template --- .github/ISSUE_TEMPLATE/1_bug.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml index 0f21f11fe..cb20aeec9 100644 --- a/.github/ISSUE_TEMPLATE/1_bug.yml +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -44,25 +44,6 @@ body: description: Please tell us what is actually happening. validations: required: true - - type: textarea - attributes: - label: Code sample - description: | - Please create a minimal reproducible sample that shows the problem - and attach it below between the lines with the backticks. - - Alternatively, you can use https://dartpad.dev/ or create a public GitHub - repository to share your sample. - value: | -
Code sample - - ```dart - [Paste your code here] - ``` - -
- validations: - required: false - type: textarea attributes: label: Additional Context From 8e5743130fc86bc9a89d1a2fe56011d1ed6f4ee7 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 20 Sep 2024 14:24:36 +0300 Subject: [PATCH 030/113] chore: rename closeWebPasteEvent() to cancelWebPasteEvent(), improve doc of _webPasteEventSubscription --- lib/src/controller/quill_controller.dart | 2 +- lib/src/controller/web/quill_controller_web_real.dart | 5 +++-- lib/src/controller/web/quill_controller_web_stub.dart | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/src/controller/quill_controller.dart b/lib/src/controller/quill_controller.dart index 2a688780d..16eae86b7 100644 --- a/lib/src/controller/quill_controller.dart +++ b/lib/src/controller/quill_controller.dart @@ -477,7 +477,7 @@ class QuillController extends ChangeNotifier { _isDisposed = true; if (kIsWeb) { - closeWebPasteEvent(); + cancelWebPasteEvent(); } super.dispose(); } diff --git a/lib/src/controller/web/quill_controller_web_real.dart b/lib/src/controller/web/quill_controller_web_real.dart index ec13e4856..017d3510b 100644 --- a/lib/src/controller/web/quill_controller_web_real.dart +++ b/lib/src/controller/web/quill_controller_web_real.dart @@ -10,7 +10,8 @@ import '../quill_controller_rich_paste.dart'; /// Paste event for the web. /// -/// Will be `null` for non-web platforms. +/// Will be `null` when [QuillControllerWeb.initializeWebPasteEvent] was not called +/// or the subscription was canceled due to calling [QuillControllerWeb.cancelWebPasteEvent] /// /// See: https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event StreamSubscription? _webPasteEventSubscription; @@ -30,7 +31,7 @@ extension QuillControllerWeb on QuillController { }); } - void closeWebPasteEvent() { + void cancelWebPasteEvent() { _webPasteEventSubscription?.cancel(); _webPasteEventSubscription = null; } diff --git a/lib/src/controller/web/quill_controller_web_stub.dart b/lib/src/controller/web/quill_controller_web_stub.dart index ef30a29a8..0f2e41189 100644 --- a/lib/src/controller/web/quill_controller_web_stub.dart +++ b/lib/src/controller/web/quill_controller_web_stub.dart @@ -12,7 +12,7 @@ extension QuillControllerWeb on QuillController { ); } - void closeWebPasteEvent() { + void cancelWebPasteEvent() { throw UnsupportedError( 'The closeWebPasteEvent() method should be called only on web.', ); From 8e6dd4f1106d1b0cd36159928c18512349abffb6 Mon Sep 17 00:00:00 2001 From: joeserhtf Date: Fri, 20 Sep 2024 15:23:41 -0300 Subject: [PATCH 031/113] Feat: Removing check not allowing spell check on web (#2252) --- lib/src/editor/widgets/text/text_line.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index a686d9f2b..9b41dc5e4 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -510,7 +510,6 @@ class _TextLineState extends State { !widget.readOnly && !widget.line.style.attributes.containsKey('code-block') && !widget.line.style.attributes.containsKey('placeholder') && - !kIsWeb && !isPlaceholderLine) { final service = SpellCheckerServiceProvider.instance; final spellcheckedSpans = service.checkSpelling(textNode.value); From eed35994d21242b556aa27c162ef5c20f4a23299 Mon Sep 17 00:00:00 2001 From: singerdmx Date: Fri, 20 Sep 2024 18:24:51 +0000 Subject: [PATCH 032/113] chore(version): update to version 10.6.6 --- CHANGELOG.md | 9 +++++++++ CHANGELOG_DATA.json | 1 + dart_quill_delta/CHANGELOG.md | 9 +++++++++ dart_quill_delta/pubspec.yaml | 2 +- flutter_quill_extensions/CHANGELOG.md | 9 +++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 9 +++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- quill_native_bridge/CHANGELOG.md | 9 +++++++++ quill_native_bridge/pubspec.yaml | 2 +- 11 files changed, 51 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d60880136..596f4097b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. +## 10.6.6 + +* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 + +## New Contributors +* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6 + ## 10.6.5 * Refine IME composing range styling by applying underline as text style by @agata in https://github.com/singerdmx/flutter-quill/pull/2244 diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index b84c8d0d0..5ce685077 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.6.6": "* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252\r\n\r\n## New Contributors\r\n* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6", "10.6.5": "* Refine IME composing range styling by applying underline as text style by @agata in https://github.com/singerdmx/flutter-quill/pull/2244\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.4...v10.6.5", "10.6.4": "* fix: the composing text did not show an underline during IME conversion by @agata in https://github.com/singerdmx/flutter-quill/pull/2242\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.3...v10.6.4", "10.6.3": "* Fix: Resolved issue with broken IME composing rect in Windows desktop by @agata in https://github.com/singerdmx/flutter-quill/pull/2239\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.2...v10.6.3", diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index d60880136..596f4097b 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. +## 10.6.6 + +* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 + +## New Contributors +* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6 + ## 10.6.5 * Refine IME composing range styling by applying underline as text style by @agata in https://github.com/singerdmx/flutter-quill/pull/2244 diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index 4b62fdfdc..2860fd70f 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 10.6.5 +version: 10.6.6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index d60880136..596f4097b 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. +## 10.6.6 + +* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 + +## New Contributors +* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6 + ## 10.6.5 * Refine IME composing range styling by applying underline as text style by @agata in https://github.com/singerdmx/flutter-quill/pull/2244 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index f537ccd7f..8bd7a4ef9 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.6.5 +version: 10.6.6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index d60880136..596f4097b 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. +## 10.6.6 + +* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 + +## New Contributors +* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6 + ## 10.6.5 * Refine IME composing range styling by applying underline as text style by @agata in https://github.com/singerdmx/flutter-quill/pull/2244 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 02a77e2a4..769bcd8a3 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.6.5 +version: 10.6.6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index a1d3100fb..91644d88b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.6.5 +version: 10.6.6 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/quill_native_bridge/CHANGELOG.md b/quill_native_bridge/CHANGELOG.md index d60880136..596f4097b 100644 --- a/quill_native_bridge/CHANGELOG.md +++ b/quill_native_bridge/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. +## 10.6.6 + +* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 + +## New Contributors +* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6 + ## 10.6.5 * Refine IME composing range styling by applying underline as text style by @agata in https://github.com/singerdmx/flutter-quill/pull/2244 diff --git a/quill_native_bridge/pubspec.yaml b/quill_native_bridge/pubspec.yaml index 9980d0ecb..00ba32af6 100644 --- a/quill_native_bridge/pubspec.yaml +++ b/quill_native_bridge/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge description: "An internal plugin for flutter_quill package to access platform-specific APIs" -version: 10.6.5 +version: 10.6.6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ repository: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 8dfac756690fe721a83070374d8d5abae20600e5 Mon Sep 17 00:00:00 2001 From: Cat <114286961+CatHood0@users.noreply.github.com> Date: Fri, 20 Sep 2024 22:04:14 -0400 Subject: [PATCH 033/113] Chore: deprecate embed table feature (#2254) --- .../lib/screens/quill/my_quill_toolbar.dart | 1 - .../lib/src/editor/table/table_cell_embed.dart | 5 +++++ .../lib/src/editor/table/table_embed.dart | 11 +++++++++++ .../lib/src/editor/table/table_models.dart | 5 +++++ .../lib/src/flutter_quill_embeds.dart | 18 ++++++++---------- .../table/models/table_configurations.dart | 8 +++++++- .../lib/src/toolbar/table/table_button.dart | 4 ++++ 7 files changed, 40 insertions(+), 12 deletions(-) diff --git a/example/lib/screens/quill/my_quill_toolbar.dart b/example/lib/screens/quill/my_quill_toolbar.dart index ef42c03cc..3c7faa524 100644 --- a/example/lib/screens/quill/my_quill_toolbar.dart +++ b/example/lib/screens/quill/my_quill_toolbar.dart @@ -302,7 +302,6 @@ class MyQuillToolbar extends StatelessWidget { : onImageInsert, ), ), - tableButtonOptions: const QuillToolbarTableButtonOptions(), ), ), ); diff --git a/flutter_quill_extensions/lib/src/editor/table/table_cell_embed.dart b/flutter_quill_extensions/lib/src/editor/table/table_cell_embed.dart index 27a4f5c69..94ae51b5b 100644 --- a/flutter_quill_extensions/lib/src/editor/table/table_cell_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/table/table_cell_embed.dart @@ -1,6 +1,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import 'package:meta/meta.dart'; +@experimental +@Deprecated( + 'TableCellWidget will no longer used and it will be removed in future releases') class TableCellWidget extends StatefulWidget { const TableCellWidget({ required this.cellId, @@ -18,6 +22,7 @@ class TableCellWidget extends StatefulWidget { State createState() => _TableCellWidgetState(); } +// ignore: deprecated_member_use_from_same_package class _TableCellWidgetState extends State { late final TextEditingController controller; late final FocusNode node; diff --git a/flutter_quill_extensions/lib/src/editor/table/table_embed.dart b/flutter_quill_extensions/lib/src/editor/table/table_embed.dart index ad8275a03..3a8cc3b90 100644 --- a/flutter_quill_extensions/lib/src/editor/table/table_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/table/table_embed.dart @@ -3,10 +3,14 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/quill_delta.dart'; +import 'package:meta/meta.dart'; import '../../common/utils/quill_table_utils.dart'; import 'table_cell_embed.dart'; import 'table_models.dart'; +@experimental +@Deprecated( + 'CustomTableEmbed will no longer used and it will be removed in future releases') class CustomTableEmbed extends CustomBlockEmbed { const CustomTableEmbed(String value) : super(tableType, value); @@ -20,6 +24,7 @@ class CustomTableEmbed extends CustomBlockEmbed { //Embed builder +@experimental class QuillEditorTableEmbedBuilder extends EmbedBuilder { @override String get key => 'table'; @@ -34,6 +39,7 @@ class QuillEditorTableEmbedBuilder extends EmbedBuilder { TextStyle textStyle, ) { final tableData = node.value.data; + // ignore: deprecated_member_use_from_same_package return TableWidget( tableData: tableData, controller: controller, @@ -41,6 +47,9 @@ class QuillEditorTableEmbedBuilder extends EmbedBuilder { } } +@experimental +@Deprecated( + 'TableWidget will no longer used and it will be removed in future releases') class TableWidget extends StatefulWidget { const TableWidget({ required this.tableData, @@ -54,6 +63,7 @@ class TableWidget extends StatefulWidget { State createState() => _TableWidgetState(); } +// ignore: deprecated_member_use_from_same_package class _TableWidgetState extends State { TableModel _tableModel = TableModel(columns: {}, rows: {}); String _selectedColumnId = ''; @@ -214,6 +224,7 @@ class _TableWidgetState extends State { if (key != 'id') { final columnId = key; final data = value; + // ignore: deprecated_member_use_from_same_package rowCells.add(TableCellWidget( cellId: rowKey, onTap: (node) { diff --git a/flutter_quill_extensions/lib/src/editor/table/table_models.dart b/flutter_quill_extensions/lib/src/editor/table/table_models.dart index 2c7ff4e9b..26a231356 100644 --- a/flutter_quill_extensions/lib/src/editor/table/table_models.dart +++ b/flutter_quill_extensions/lib/src/editor/table/table_models.dart @@ -1,3 +1,6 @@ +import 'package:meta/meta.dart'; + +@experimental class TableModel { TableModel({required this.columns, required this.rows}); @@ -42,6 +45,7 @@ class TableModel { } } +@experimental class ColumnModel { ColumnModel({required this.id, required this.position}); @@ -62,6 +66,7 @@ class ColumnModel { } } +@experimental class RowModel { // Key is column ID, value is cell content diff --git a/flutter_quill_extensions/lib/src/flutter_quill_embeds.dart b/flutter_quill_extensions/lib/src/flutter_quill_embeds.dart index 03023d26f..cfaa1b7d2 100644 --- a/flutter_quill_extensions/lib/src/flutter_quill_embeds.dart +++ b/flutter_quill_extensions/lib/src/flutter_quill_embeds.dart @@ -1,10 +1,9 @@ import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter_quill/flutter_quill.dart' as fq; -import 'package:meta/meta.dart' show immutable; +import 'package:meta/meta.dart' show experimental, immutable; import 'editor/image/image_embed.dart'; import 'editor/image/models/image_configurations.dart'; -import 'editor/table/table_embed.dart'; import 'editor/video/models/video_configurations.dart'; import 'editor/video/models/video_web_configurations.dart'; import 'editor/video/video_embed.dart'; @@ -14,7 +13,6 @@ import 'toolbar/camera/models/camera_configurations.dart'; import 'toolbar/image/image_button.dart'; import 'toolbar/image/models/image_configurations.dart'; import 'toolbar/table/models/table_configurations.dart'; -import 'toolbar/table/table_button.dart'; import 'toolbar/video/models/video_configurations.dart'; import 'toolbar/video/video_button.dart'; @@ -62,7 +60,10 @@ class FlutterQuillEmbeds { QuillEditorVideoEmbedBuilder( configurations: videoEmbedConfigurations, ), - QuillEditorTableEmbedBuilder(), + // We disable the table feature is in experimental phase + // and it does not work as we expect + // https://github.com/singerdmx/flutter-quill/pull/2238#pullrequestreview-2312706901 + // QuillEditorTableEmbedBuilder(), ]; } @@ -119,6 +120,9 @@ class FlutterQuillEmbeds { QuillToolbarVideoButtonOptions? videoButtonOptions = const QuillToolbarVideoButtonOptions(), QuillToolbarCameraButtonOptions? cameraButtonOptions, + @experimental + @Deprecated( + 'tableButtonOptions will no longer used by now, and probably will be removed in future releases.') QuillToolbarTableButtonOptions? tableButtonOptions, }) => [ @@ -140,11 +144,5 @@ class FlutterQuillEmbeds { controller: controller, options: cameraButtonOptions, ), - if (tableButtonOptions != null) - (controller, toolbarIconSize, iconTheme, dialogTheme) => - QuillToolbarTableButton( - controller: controller, - options: tableButtonOptions, - ), ]; } diff --git a/flutter_quill_extensions/lib/src/toolbar/table/models/table_configurations.dart b/flutter_quill_extensions/lib/src/toolbar/table/models/table_configurations.dart index 27d9a44e7..028391266 100644 --- a/flutter_quill_extensions/lib/src/toolbar/table/models/table_configurations.dart +++ b/flutter_quill_extensions/lib/src/toolbar/table/models/table_configurations.dart @@ -1,6 +1,9 @@ import 'package:flutter_quill/flutter_quill.dart'; -import 'package:meta/meta.dart' show immutable; +import 'package:meta/meta.dart' show experimental, immutable; +@experimental +@Deprecated( + 'QuillToolbarTableButtonExtraOptions is not stable at this moment and it should not be used. Probably will be removed in future releases') class QuillToolbarTableButtonExtraOptions extends QuillToolbarBaseButtonExtraOptions { const QuillToolbarTableButtonExtraOptions({ @@ -11,6 +14,9 @@ class QuillToolbarTableButtonExtraOptions } @immutable +@experimental +@Deprecated( + 'QuillToolbarTableButton is not stable at this moment and it should not be used. Probably will be removed in future releases') class QuillToolbarTableButtonOptions extends QuillToolbarBaseButtonOptions< QuillToolbarTableButtonOptions, QuillToolbarTableButtonExtraOptions> { const QuillToolbarTableButtonOptions({ diff --git a/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart b/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart index d8ae64664..dd0fabf30 100644 --- a/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart +++ b/flutter_quill_extensions/lib/src/toolbar/table/table_button.dart @@ -1,10 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter_quill/translations.dart'; +import 'package:meta/meta.dart'; import '../../common/utils/quill_table_utils.dart'; import 'models/table_configurations.dart'; +@experimental +@Deprecated( + 'QuillToolbarTableButton will no longer used and will be removed in future releases') class QuillToolbarTableButton extends StatelessWidget { const QuillToolbarTableButton({ required this.controller, From 55fbb16fa7b16a8745dd8fa0e496ca8492953ff1 Mon Sep 17 00:00:00 2001 From: singerdmx Date: Sat, 21 Sep 2024 02:07:59 +0000 Subject: [PATCH 034/113] chore(version): update to version 10.7.0 --- CHANGELOG.md | 7 +++++++ CHANGELOG_DATA.json | 1 + dart_quill_delta/CHANGELOG.md | 7 +++++++ dart_quill_delta/pubspec.yaml | 2 +- flutter_quill_extensions/CHANGELOG.md | 7 +++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 7 +++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- quill_native_bridge/CHANGELOG.md | 7 +++++++ quill_native_bridge/pubspec.yaml | 2 +- 11 files changed, 41 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 596f4097b..de718dc7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.0 + +* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0 + ## 10.6.6 * Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index 5ce685077..55f497188 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.7.0": "* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0", "10.6.6": "* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252\r\n\r\n## New Contributors\r\n* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6", "10.6.5": "* Refine IME composing range styling by applying underline as text style by @agata in https://github.com/singerdmx/flutter-quill/pull/2244\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.4...v10.6.5", "10.6.4": "* fix: the composing text did not show an underline during IME conversion by @agata in https://github.com/singerdmx/flutter-quill/pull/2242\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.3...v10.6.4", diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index 596f4097b..de718dc7f 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.0 + +* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0 + ## 10.6.6 * Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index 2860fd70f..80083a771 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 10.6.6 +version: 10.7.0 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 596f4097b..de718dc7f 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.0 + +* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0 + ## 10.6.6 * Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 8bd7a4ef9..ebeb963ad 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.6.6 +version: 10.7.0 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 596f4097b..de718dc7f 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.0 + +* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0 + ## 10.6.6 * Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 769bcd8a3..30b03f165 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.6.6 +version: 10.7.0 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 91644d88b..b75d8767c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.6.6 +version: 10.7.0 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/quill_native_bridge/CHANGELOG.md b/quill_native_bridge/CHANGELOG.md index 596f4097b..de718dc7f 100644 --- a/quill_native_bridge/CHANGELOG.md +++ b/quill_native_bridge/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.0 + +* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0 + ## 10.6.6 * Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 diff --git a/quill_native_bridge/pubspec.yaml b/quill_native_bridge/pubspec.yaml index 00ba32af6..92577ffa6 100644 --- a/quill_native_bridge/pubspec.yaml +++ b/quill_native_bridge/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge description: "An internal plugin for flutter_quill package to access platform-specific APIs" -version: 10.6.6 +version: 10.7.0 homepage: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ repository: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 03fc81c21e7280a264e165336769c98f9ae62c96 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 21 Sep 2024 05:09:14 +0300 Subject: [PATCH 035/113] chore: deprecate markdown_quill export, ignore warnings (#2256) --- lib/markdown_quill.dart | 9 ++++++--- lib/src/delta/delta_x.dart | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/markdown_quill.dart b/lib/markdown_quill.dart index 50e11442b..326b5d542 100644 --- a/lib/markdown_quill.dart +++ b/lib/markdown_quill.dart @@ -1,6 +1,9 @@ -library quill_markdown; - -// TODO: Might avoid exposing the quill_markdown package +@Deprecated( + 'markdown_quill is no longer part of public API and will be removed in future releases.' + 'See https://pub.dev/packages/markdown_quill or ' + 'https://pub.dev/packages/quill_markdown as alternatives.', +) +library; export 'src/packages/quill_markdown/delta_to_markdown.dart'; export 'src/packages/quill_markdown/embeddable_table_syntax.dart'; diff --git a/lib/src/delta/delta_x.dart b/lib/src/delta/delta_x.dart index 915f67bc2..45da51bee 100644 --- a/lib/src/delta/delta_x.dart +++ b/lib/src/delta/delta_x.dart @@ -3,6 +3,7 @@ import 'package:flutter_quill_delta_from_html/flutter_quill_delta_from_html.dart import 'package:markdown/markdown.dart' as md; import 'package:meta/meta.dart' show experimental; +// ignore: deprecated_member_use_from_same_package import '../../markdown_quill.dart'; import '../../quill_delta.dart'; From 708baf2ed4138e809aebe70b3ab0ae03a8ccd914 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 21 Sep 2024 05:09:57 +0300 Subject: [PATCH 036/113] chore: deprecate spell checker service (#2255) * chore: deprecate SpellCheckerService * docs(readme): update docs to reflect the change * chore: deprecate DefaultSpellCheckerService and SpellCheckerServiceProvider, ignore all warnings --- README.md | 7 +- doc/spell_checker.md | 79 ------------------- .../lib/screens/home/widgets/home_screen.dart | 1 + example/lib/screens/quill/quill_screen.dart | 2 + .../simple_spell_checker_service.dart | 7 +- example/lib/spell_checker/spell_checker.dart | 2 + .../default_spellchecker_service.dart | 9 +++ .../spellchecker/spellchecker_service.dart | 7 ++ .../spellchecker_service_provider.dart | 9 +++ lib/src/editor/widgets/text/text_line.dart | 1 + 10 files changed, 39 insertions(+), 85 deletions(-) delete mode 100644 doc/spell_checker.md diff --git a/README.md b/README.md index 9e9a5473d..b48375331 100644 --- a/README.md +++ b/README.md @@ -286,11 +286,8 @@ The following packages can be used: ## 📝 Spelling checker -While spell-checking is not a feature that's implemented into the project, it can be used using external dependencies. - -It's implemented using the package `simple_spell_checker` in the [Example](./example/). - -Take a look at [Spelling Checker](./doc/spell_checker.md) page for more info. +This feature is currently not implemented and is being planned. Refer to [#2246](https://github.com/singerdmx/flutter-quill/issues/2246) +for discussion. ## ✂️ Shortcut events diff --git a/doc/spell_checker.md b/doc/spell_checker.md deleted file mode 100644 index 5fc3e56b5..000000000 --- a/doc/spell_checker.md +++ /dev/null @@ -1,79 +0,0 @@ -# 📝 Spelling checker - -A spell checker is a software tool or feature integrated into various text processing applications that automatically identifies and corrects spelling errors in a written document. It works by comparing the words in the text against a built-in dictionary. If a word isn't found in the dictionary or doesn't match any known word patterns, the spell checker highlights it as a potential error. - -While spell-checking is not a feature that's implemented into the project, it can be used using external dependencies. - -It's implemented using the package `simple_spell_checker` in the [Example](../example/). - -> [!NOTE] -> [`simple_spell_checker`](https://pub.dev/packages/simple_spell_checker) is a client-side dependency that works without an internet connection, so, it could weigh more than expected due to each of the dictionaries. As mentioned below, it supports a very wide variety of languages which can have a file of up to 300.000 words (this being just one language). - -### Benefits of a spell checker include: - -* Improved Accuracy: It helps writers avoid common spelling mistakes, ensuring that the text is free of errors. -* Time-Saving: Automatically detecting errors reduces the time needed for manual proofreading. -* Enhanced Professionalism: Correctly spelled words contribute to the overall professionalism of documents, which is crucial in academic, business, and formal writing. -* Multilingual Support: Many spell checkers support multiple languages, making it easier for users to write accurately in different languages. - -> [!IMPORTANT] -> The spell checker usually does not work as expected in most cases. For now it is a purely **experimental** feature that may have **code that will be modified** in future versions. - -### The translations supported so far are: - -* German - `de`, `de-ch` -* English - `en`, `en-gb` -* Spanish - `es` -* Catalan - `ca` -* Arabic - `ar` -* Danish - `da` -* French - `fr` -* Bulgarian - `bg` -* Dutch - `nl` -* Korean - `ko` -* Estonian - `et` -* Hebrew - `he` -* Slovak - `sk` -* Italian - `it` -* Norwegian - `no` -* Portuguese - `pt` -* Swedish - `sv` -* Russian - `ru` - -_**Note**: If you have knowledge about any of these available languages or the unsupported ones, you can make a pull request to add support or add words that are not currently in [simple_spell_checker](https://github.com/CatHood0/simple_spell_checker)_. - -In order to activate this functionality you can use the following code: - -```dart -// you can use the language of your preference or directly select the language of the operating system -final language = 'en'; // or Localizations.localeOf(context).languageCode -SpellChecker.useSpellCheckerService(language); -``` - -> [!NOTE] -> The class `SpellChecker` is not available as part of the project API. Instead, you will have to implement it manually. Take a look at the example [Spell Checker](../example/lib/spell_checker/spell_checker.dart) class. - -When you no longer need to have the Spell checker activated you can simply use `dispose()` of the `SpellCheckerServiceProvider` class: - -```dart -// dispose all service and it cannot be used after this -SpellCheckerServiceProvider.dispose(); -``` - -If what we want is to **close the StreamControllers** without deleting the values that are already stored in it, we can set `onlyPartial` to `true`. - -```dart -// it can be still used by the editor -SpellCheckerServiceProvider.dispose(onlyPartial: true); -``` - -One use of this would be having the opportunity to **activate and deactivate** the service when we want, we can see this in the example that we have in this package, in which you can see that on each screen, we have a button that dynamically activates and deactivates the service. To do this is pretty simple: - -```dart - SpellCheckerServiceProvider.toggleState(); - // use isServiceActive to get the state of the service - SpellCheckerServiceProvider.isServiceActive(); - setState(() {}); -``` - -Open this [page](https://pub.dev/packages/simple_spell_checker) for more information. \ No newline at end of file diff --git a/example/lib/screens/home/widgets/home_screen.dart b/example/lib/screens/home/widgets/home_screen.dart index a0056d571..c75a6e514 100644 --- a/example/lib/screens/home/widgets/home_screen.dart +++ b/example/lib/screens/home/widgets/home_screen.dart @@ -27,6 +27,7 @@ class HomeScreen extends StatefulWidget { class _HomeScreenState extends State { @override void dispose() { + // ignore: deprecated_member_use SpellCheckerServiceProvider.dispose(); super.dispose(); } diff --git a/example/lib/screens/quill/quill_screen.dart b/example/lib/screens/quill/quill_screen.dart index 9b59e7669..4afefe6f1 100644 --- a/example/lib/screens/quill/quill_screen.dart +++ b/example/lib/screens/quill/quill_screen.dart @@ -70,11 +70,13 @@ class _QuillScreenState extends State { IconButton( tooltip: 'Spell-checker', onPressed: () { + // ignore: deprecated_member_use SpellCheckerServiceProvider.toggleState(); setState(() {}); }, icon: Icon( Icons.document_scanner, + // ignore: deprecated_member_use color: SpellCheckerServiceProvider.isServiceActive() ? Colors.red.withOpacity(0.5) : null, diff --git a/example/lib/spell_checker/simple_spell_checker_service.dart b/example/lib/spell_checker/simple_spell_checker_service.dart index c804a8d19..26c109e11 100644 --- a/example/lib/spell_checker/simple_spell_checker_service.dart +++ b/example/lib/spell_checker/simple_spell_checker_service.dart @@ -4,8 +4,13 @@ import 'package:flutter_quill/flutter_quill.dart'; import 'package:simple_spell_checker/simple_spell_checker.dart'; /// SimpleSpellChecker is a simple spell checker for get -/// all words divide on different objects if them are wrong or not +/// all words divide on different objects if them are wrong or not. +/// +/// **Important**: A breaking change is planned and this shouldn't be used +/// for new applications. A replacement will arrive soon. +/// See: https://github.com/singerdmx/flutter-quill/issues/2246 class SimpleSpellCheckerService + // ignore: deprecated_member_use extends SpellCheckerService { SimpleSpellCheckerService({required super.language}) : checker = SimpleSpellChecker( diff --git a/example/lib/spell_checker/spell_checker.dart b/example/lib/spell_checker/spell_checker.dart index 08238ce17..df9eea350 100644 --- a/example/lib/spell_checker/spell_checker.dart +++ b/example/lib/spell_checker/spell_checker.dart @@ -1,3 +1,5 @@ +// ignore_for_file: deprecated_member_use + import 'package:flutter_quill/flutter_quill.dart'; import 'simple_spell_checker_service.dart'; diff --git a/lib/src/editor/spellchecker/default_spellchecker_service.dart b/lib/src/editor/spellchecker/default_spellchecker_service.dart index 4a8e6b1ad..79ec19c0a 100644 --- a/lib/src/editor/spellchecker/default_spellchecker_service.dart +++ b/lib/src/editor/spellchecker/default_spellchecker_service.dart @@ -1,10 +1,19 @@ +// ignore_for_file: deprecated_member_use_from_same_package + import 'package:flutter/gestures.dart' show LongPressGestureRecognizer; import 'package:flutter/material.dart' show TextSpan; +import 'package:meta/meta.dart'; import 'spellchecker_service.dart' show SpellCheckerService; /// A default implementation of the [SpellcheckerService] /// that always will return null since Spell checking /// is not a standard feature +@Deprecated( + 'A breaking change is being planned for the SpellCheckerService and SpellCheckerServiceProvider.\n' + "A replacement doesn't exist yet but should arrive soon." + 'See https://github.com/singerdmx/flutter-quill/issues/2246 for more details.', +) +@experimental class DefaultSpellCheckerService extends SpellCheckerService { DefaultSpellCheckerService() : super(language: 'en'); diff --git a/lib/src/editor/spellchecker/spellchecker_service.dart b/lib/src/editor/spellchecker/spellchecker_service.dart index 0e2ebd48c..41b34678f 100644 --- a/lib/src/editor/spellchecker/spellchecker_service.dart +++ b/lib/src/editor/spellchecker/spellchecker_service.dart @@ -1,7 +1,14 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:meta/meta.dart'; /// A representation a custom SpellCheckService. +@Deprecated( + 'A breaking change is being planned for the SpellCheckerService.\n' + "A replacement doesn't exist yet but should arrive soon." + 'See https://github.com/singerdmx/flutter-quill/issues/2246 for more details.', +) +@experimental abstract class SpellCheckerService { SpellCheckerService({required this.language}); diff --git a/lib/src/editor/spellchecker/spellchecker_service_provider.dart b/lib/src/editor/spellchecker/spellchecker_service_provider.dart index e5d41335f..47e80182d 100644 --- a/lib/src/editor/spellchecker/spellchecker_service_provider.dart +++ b/lib/src/editor/spellchecker/spellchecker_service_provider.dart @@ -1,8 +1,17 @@ +// ignore_for_file: deprecated_member_use_from_same_package + import 'package:flutter/foundation.dart' show immutable; +import 'package:meta/meta.dart' show experimental; import 'default_spellchecker_service.dart'; import 'spellchecker_service.dart'; @immutable +@Deprecated( + 'A breaking change is being planned for the SpellCheckerService and SpellCheckerServiceProvider.\n' + "A replacement doesn't exist yet but should arrive soon." + 'See https://github.com/singerdmx/flutter-quill/issues/2246 for more details.', +) +@experimental class SpellCheckerServiceProvider { const SpellCheckerServiceProvider._(); static SpellCheckerService _instance = DefaultSpellCheckerService(); diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 9b41dc5e4..69cea2e88 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -511,6 +511,7 @@ class _TextLineState extends State { !widget.line.style.attributes.containsKey('code-block') && !widget.line.style.attributes.containsKey('placeholder') && !isPlaceholderLine) { + // ignore: deprecated_member_use_from_same_package final service = SpellCheckerServiceProvider.instance; final spellcheckedSpans = service.checkSpelling(textNode.value); if (spellcheckedSpans != null && spellcheckedSpans.isNotEmpty) { From ec520c4d2f72e5ce1fb415c0554c351de87c0df2 Mon Sep 17 00:00:00 2001 From: singerdmx Date: Sat, 21 Sep 2024 04:32:42 +0000 Subject: [PATCH 037/113] chore(version): update to version 10.7.1 --- CHANGELOG.md | 8 ++++++++ CHANGELOG_DATA.json | 1 + dart_quill_delta/CHANGELOG.md | 8 ++++++++ dart_quill_delta/pubspec.yaml | 2 +- flutter_quill_extensions/CHANGELOG.md | 8 ++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 8 ++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- quill_native_bridge/CHANGELOG.md | 8 ++++++++ quill_native_bridge/pubspec.yaml | 2 +- 11 files changed, 46 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de718dc7f..4f2fa6bae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.1 + +* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 +* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1 + ## 10.7.0 * Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index 55f497188..e0a78f395 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.7.1": "* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256\r\n* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1", "10.7.0": "* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0", "10.6.6": "* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252\r\n\r\n## New Contributors\r\n* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6", "10.6.5": "* Refine IME composing range styling by applying underline as text style by @agata in https://github.com/singerdmx/flutter-quill/pull/2244\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.4...v10.6.5", diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index de718dc7f..4f2fa6bae 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.1 + +* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 +* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1 + ## 10.7.0 * Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index 80083a771..115aceaa3 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 10.7.0 +version: 10.7.1 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index de718dc7f..4f2fa6bae 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.1 + +* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 +* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1 + ## 10.7.0 * Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index ebeb963ad..8aedc8ec9 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.7.0 +version: 10.7.1 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index de718dc7f..4f2fa6bae 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.1 + +* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 +* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1 + ## 10.7.0 * Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 30b03f165..79621229e 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.7.0 +version: 10.7.1 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index b75d8767c..8c3010ba3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.7.0 +version: 10.7.1 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/quill_native_bridge/CHANGELOG.md b/quill_native_bridge/CHANGELOG.md index de718dc7f..4f2fa6bae 100644 --- a/quill_native_bridge/CHANGELOG.md +++ b/quill_native_bridge/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.1 + +* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 +* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1 + ## 10.7.0 * Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 diff --git a/quill_native_bridge/pubspec.yaml b/quill_native_bridge/pubspec.yaml index 92577ffa6..21fc76e07 100644 --- a/quill_native_bridge/pubspec.yaml +++ b/quill_native_bridge/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge description: "An internal plugin for flutter_quill package to access platform-specific APIs" -version: 10.7.0 +version: 10.7.1 homepage: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ repository: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 35546cab2d80d22fc10a80d8e8488433b160c08c Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 21 Sep 2024 15:21:31 +0300 Subject: [PATCH 038/113] chore: deprecate flutter_quill/extensions.dart (#2258) * chore: deprecate flutter_quill/extensions.dart * chore: remove all usages of extensions.dart in flutter_quill --- .../lib/screens/quill/my_quill_editor.dart | 2 +- .../lib/screens/quill/my_quill_toolbar.dart | 2 +- .../utils/element_utils/element_utils.dart | 2 +- .../lib/src/editor/image/image_menu.dart | 2 +- .../image/models/image_configurations.dart | 2 +- .../toolbar/camera/select_camera_action.dart | 2 +- .../toolbar/image/select_image_source.dart | 2 +- .../toolbar/video/select_video_source.dart | 2 +- lib/extensions.dart | 5 +++++ lib/flutter_quill_internal.dart | 21 +++++++++++++++++++ .../editor/embed/embed_editor_builder.dart | 2 +- lib/src/toolbar/buttons/clipboard_button.dart | 2 +- .../toolbar/buttons/font_family_button.dart | 2 +- lib/src/toolbar/buttons/font_size_button.dart | 2 +- .../toolbar/buttons/link_style2_button.dart | 4 ++-- .../toolbar/buttons/search/search_dialog.dart | 3 ++- 16 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 lib/flutter_quill_internal.dart diff --git a/example/lib/screens/quill/my_quill_editor.dart b/example/lib/screens/quill/my_quill_editor.dart index 505a9a09c..ad5eb13e5 100644 --- a/example/lib/screens/quill/my_quill_editor.dart +++ b/example/lib/screens/quill/my_quill_editor.dart @@ -5,8 +5,8 @@ import 'package:cached_network_image/cached_network_image.dart' import 'package:desktop_drop/desktop_drop.dart' show DropTarget; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; -import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; // ignore: implementation_imports import 'package:flutter_quill_extensions/src/editor/image/widgets/image.dart' diff --git a/example/lib/screens/quill/my_quill_toolbar.dart b/example/lib/screens/quill/my_quill_toolbar.dart index 3c7faa524..ef13bd34d 100644 --- a/example/lib/screens/quill/my_quill_toolbar.dart +++ b/example/lib/screens/quill/my_quill_toolbar.dart @@ -3,8 +3,8 @@ import 'dart:io' as io show File; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart'; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:image_cropper/image_cropper.dart'; diff --git a/flutter_quill_extensions/lib/src/common/utils/element_utils/element_utils.dart b/flutter_quill_extensions/lib/src/common/utils/element_utils/element_utils.dart index 6be7c1635..a350f288e 100644 --- a/flutter_quill_extensions/lib/src/common/utils/element_utils/element_utils.dart +++ b/flutter_quill_extensions/lib/src/common/utils/element_utils/element_utils.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/widgets.dart' show Alignment, BuildContext; -import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart' show Attribute, Node; +import 'package:flutter_quill/flutter_quill_internal.dart'; import 'element_shared_utils.dart'; diff --git a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart index c0efff770..36e009c5c 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart @@ -1,9 +1,9 @@ import 'package:flutter/cupertino.dart' show showCupertinoModalPopup; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; -import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/flutter_quill.dart' show ImageUrl, QuillController, StyleAttribute, getEmbedNode; +import 'package:flutter_quill/flutter_quill_internal.dart'; import 'package:flutter_quill/translations.dart'; import 'package:super_clipboard/super_clipboard.dart'; diff --git a/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart b/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart index f8edcf0a7..8af3527f3 100644 --- a/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart +++ b/flutter_quill_extensions/lib/src/editor/image/models/image_configurations.dart @@ -1,7 +1,7 @@ import 'dart:io' show File; import 'package:flutter/foundation.dart'; -import 'package:flutter_quill/extensions.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart'; import '../image_embed_types.dart'; diff --git a/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart b/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart index 28e66da66..5d10de8b2 100644 --- a/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart +++ b/flutter_quill_extensions/lib/src/toolbar/camera/select_camera_action.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_quill/extensions.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart'; import 'package:flutter_quill/translations.dart'; import 'camera_types.dart'; diff --git a/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart b/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart index d67d11125..2a7241a25 100644 --- a/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart +++ b/flutter_quill_extensions/lib/src/toolbar/image/select_image_source.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_quill/extensions.dart' show isDesktopApp; +import 'package:flutter_quill/flutter_quill_internal.dart' show isDesktopApp; import 'package:flutter_quill/translations.dart'; import '../../editor/image/image_embed_types.dart'; diff --git a/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart b/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart index 0c3126ef0..c19080f1a 100644 --- a/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart +++ b/flutter_quill_extensions/lib/src/toolbar/video/select_video_source.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_quill/extensions.dart' show isDesktopApp; +import 'package:flutter_quill/flutter_quill_internal.dart' show isDesktopApp; import 'package:flutter_quill/translations.dart'; import 'models/video.dart'; diff --git a/lib/extensions.dart b/lib/extensions.dart index 002d1bd9e..96226bc9f 100644 --- a/lib/extensions.dart +++ b/lib/extensions.dart @@ -1,3 +1,8 @@ +@Deprecated( + 'The extensions.dart file was primarily intended for flutter_quill_extensions ' + 'to expose certain internal APIs and should not be used directly, as it is subject to breaking changes.\n' + 'The replacement is flutter_quill_internal.dart which is also for internal use only.', +) library flutter_quill.extensions; // This file contains exports that are meant to be used diff --git a/lib/flutter_quill_internal.dart b/lib/flutter_quill_internal.dart new file mode 100644 index 000000000..215778ee1 --- /dev/null +++ b/lib/flutter_quill_internal.dart @@ -0,0 +1,21 @@ +// WARNING: This file is for internal use for flutter_quill_extensions +// and other related packages. Breaking changes +// can be introduced in minor versions. + +@experimental +library; + +// This file contains exports that are meant to be used +// internally and are not part of the public API as +// breaking changes can happen. + +import 'package:meta/meta.dart' show experimental; + +export 'src/common/utils/platform.dart'; +export 'src/common/utils/string.dart'; +export 'src/common/utils/widgets.dart'; +export 'src/document/nodes/leaf.dart'; +export 'src/rules/delete.dart'; +export 'src/rules/format.dart'; +export 'src/rules/insert.dart'; +export 'src/rules/rule.dart'; diff --git a/lib/src/editor/embed/embed_editor_builder.dart b/lib/src/editor/embed/embed_editor_builder.dart index 3710db91a..00391b45e 100644 --- a/lib/src/editor/embed/embed_editor_builder.dart +++ b/lib/src/editor/embed/embed_editor_builder.dart @@ -1,8 +1,8 @@ import 'package:flutter/widgets.dart'; -import '../../../extensions.dart'; import '../../controller/quill_controller.dart'; import '../../document/nodes/leaf.dart' as leaf; +import '../../document/nodes/leaf.dart'; abstract class EmbedBuilder { const EmbedBuilder(); diff --git a/lib/src/toolbar/buttons/clipboard_button.dart b/lib/src/toolbar/buttons/clipboard_button.dart index 2c2be1ec1..b66ffbb62 100644 --- a/lib/src/toolbar/buttons/clipboard_button.dart +++ b/lib/src/toolbar/buttons/clipboard_button.dart @@ -3,8 +3,8 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../../../extensions.dart'; import '../../../flutter_quill.dart'; +import '../../common/utils/widgets.dart'; import '../../editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; diff --git a/lib/src/toolbar/buttons/font_family_button.dart b/lib/src/toolbar/buttons/font_family_button.dart index f759383cf..89742fb4a 100644 --- a/lib/src/toolbar/buttons/font_family_button.dart +++ b/lib/src/toolbar/buttons/font_family_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../../extensions.dart'; +import '../../common/utils/widgets.dart'; import '../../document/attribute.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; diff --git a/lib/src/toolbar/buttons/font_size_button.dart b/lib/src/toolbar/buttons/font_size_button.dart index bf94591d3..eb825bd67 100644 --- a/lib/src/toolbar/buttons/font_size_button.dart +++ b/lib/src/toolbar/buttons/font_size_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import '../../../extensions.dart'; import '../../common/utils/font.dart'; +import '../../common/utils/widgets.dart'; import '../../document/attribute.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; diff --git a/lib/src/toolbar/buttons/link_style2_button.dart b/lib/src/toolbar/buttons/link_style2_button.dart index 69528532b..3a77102e4 100644 --- a/lib/src/toolbar/buttons/link_style2_button.dart +++ b/lib/src/toolbar/buttons/link_style2_button.dart @@ -2,13 +2,13 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:url_launcher/link.dart'; -import '../../../extensions.dart' - show UtilityWidgets, AutoFormatMultipleLinksRule; +import '../../common/utils/widgets.dart'; import '../../controller/quill_controller.dart'; import '../../editor/widgets/link.dart'; import '../../editor_toolbar_shared/quill_configurations_ext.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../../l10n/widgets/localizations.dart'; +import '../../rules/insert.dart'; import '../base_button/base_value_button.dart'; import '../base_toolbar.dart'; import '../simple_toolbar_provider.dart'; diff --git a/lib/src/toolbar/buttons/search/search_dialog.dart b/lib/src/toolbar/buttons/search/search_dialog.dart index 72d959ef1..dc5648d2e 100644 --- a/lib/src/toolbar/buttons/search/search_dialog.dart +++ b/lib/src/toolbar/buttons/search/search_dialog.dart @@ -2,9 +2,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import '../../../../extensions.dart'; +import '../../../common/utils/platform.dart'; import '../../../controller/quill_controller.dart'; import '../../../document/document.dart'; +import '../../../document/nodes/leaf.dart'; import '../../../l10n/extensions/localizations_ext.dart'; import '../../../l10n/widgets/localizations.dart'; import '../../theme/quill_dialog_theme.dart'; From e228f146d61f313f1adff92fe7a83ac95fe19d45 Mon Sep 17 00:00:00 2001 From: EchoEllet Date: Sat, 21 Sep 2024 12:24:30 +0000 Subject: [PATCH 039/113] chore(version): update to version 10.7.2 --- CHANGELOG.md | 10 ++++++++++ CHANGELOG_DATA.json | 1 + dart_quill_delta/CHANGELOG.md | 10 ++++++++++ dart_quill_delta/pubspec.yaml | 2 +- flutter_quill_extensions/CHANGELOG.md | 10 ++++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 10 ++++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- quill_native_bridge/CHANGELOG.md | 10 ++++++++++ quill_native_bridge/pubspec.yaml | 2 +- 11 files changed, 56 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f2fa6bae..8da2a83ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. +## 10.7.2 + +## What's Changed +* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258 + +This is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`. + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2 + ## 10.7.1 * chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index e0a78f395..e498c9fce 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.7.2": "## What's Changed\r\n* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258\r\n\r\nThis is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`.\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2", "10.7.1": "* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256\r\n* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1", "10.7.0": "* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0", "10.6.6": "* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252\r\n\r\n## New Contributors\r\n* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6", diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index 4f2fa6bae..8da2a83ad 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. +## 10.7.2 + +## What's Changed +* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258 + +This is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`. + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2 + ## 10.7.1 * chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index 115aceaa3..33a04b208 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 10.7.1 +version: 10.7.2 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 4f2fa6bae..8da2a83ad 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. +## 10.7.2 + +## What's Changed +* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258 + +This is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`. + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2 + ## 10.7.1 * chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 8aedc8ec9..8a99613c4 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.7.1 +version: 10.7.2 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 4f2fa6bae..8da2a83ad 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. +## 10.7.2 + +## What's Changed +* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258 + +This is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`. + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2 + ## 10.7.1 * chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 79621229e..cd814c334 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.7.1 +version: 10.7.2 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 8c3010ba3..6a69ccf72 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.7.1 +version: 10.7.2 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/quill_native_bridge/CHANGELOG.md b/quill_native_bridge/CHANGELOG.md index 4f2fa6bae..8da2a83ad 100644 --- a/quill_native_bridge/CHANGELOG.md +++ b/quill_native_bridge/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. +## 10.7.2 + +## What's Changed +* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258 + +This is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`. + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2 + ## 10.7.1 * chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 diff --git a/quill_native_bridge/pubspec.yaml b/quill_native_bridge/pubspec.yaml index 21fc76e07..799ddccb7 100644 --- a/quill_native_bridge/pubspec.yaml +++ b/quill_native_bridge/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge description: "An internal plugin for flutter_quill package to access platform-specific APIs" -version: 10.7.1 +version: 10.7.2 homepage: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ repository: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 4076c983370a154bd7dd9cc1b1804cce542e5c5e Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 21 Sep 2024 15:27:52 +0300 Subject: [PATCH 040/113] chore: update minimum version of flutter_quill and super_clipboard in flutter_quill_extensions --- flutter_quill_extensions/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 8a99613c4..30380f6bf 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -35,7 +35,7 @@ dependencies: universal_html: ^2.2.4 cross_file: ^0.3.3+6 - flutter_quill: ^10.3.0 + flutter_quill: ^10.7.2 photo_view: ^0.15.0 youtube_explode_dart: ^2.2.1 @@ -43,7 +43,7 @@ dependencies: video_player: ^2.8.1 youtube_player_flutter: ^9.0.1 url_launcher: ^6.2.1 - super_clipboard: ^0.8.20 + super_clipboard: ^0.8.22 gal: ^2.3.0 gal_linux: ^0.1.0 image_picker: ^1.0.4 From 503ad20645884f51e224d0b79ac50c76b41797e3 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 21 Sep 2024 15:31:23 +0300 Subject: [PATCH 041/113] chore: deprecate FlutterQuillExtensions --- example/lib/main.dart | 1 + .../lib/flutter_quill_extensions.dart | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 2a8ed52ce..532697a44 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -30,6 +30,7 @@ void main() async { ? HydratedStorage.webStorageDirectory : await getApplicationDocumentsDirectory(), ); + // ignore: deprecated_member_use FlutterQuillExtensions.useSuperClipboardPlugin(); runApp(const MyApp()); } diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 5b371598e..7a9bec821 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -2,7 +2,7 @@ library flutter_quill_extensions; // ignore: implementation_imports import 'package:flutter_quill/src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; -import 'package:meta/meta.dart' show immutable; +import 'package:meta/meta.dart' show experimental; import 'src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart'; @@ -38,9 +38,12 @@ export 'src/toolbar/video/models/video.dart'; export 'src/toolbar/video/models/video_configurations.dart'; export 'src/toolbar/video/video_button.dart'; -@immutable +@Deprecated( + 'Should not be used as will removed soon in future releases.', +) +@experimental class FlutterQuillExtensions { - const FlutterQuillExtensions._(); + FlutterQuillExtensions._(); @Deprecated( ''' @@ -51,6 +54,7 @@ class FlutterQuillExtensions { Calling this function will no longer activate the feature. ''', ) + @experimental static void useSpellCheckerService(String language) { // This feature has been removed from the package. // See https://github.com/singerdmx/flutter-quill/issues/2142 @@ -59,6 +63,11 @@ class FlutterQuillExtensions { /// Override default implementation of [ClipboardServiceProvider.instance] /// to allow `flutter_quill` package to use `super_clipboard` plugin /// to support rich text features, gif and images. + @Deprecated( + 'Should not be used anymore as super_clipboard will moved outside of flutter_quill_extensions soon.\n' + 'A replacement is being made in https://github.com/singerdmx/flutter-quill/pull/2230', + ) + @experimental static void useSuperClipboardPlugin() { ClipboardServiceProvider.setInstance(SuperClipboardService()); } From d2606a49c04acacb3c2c71302110b2f03a9e08a0 Mon Sep 17 00:00:00 2001 From: EchoEllet Date: Sat, 21 Sep 2024 12:38:27 +0000 Subject: [PATCH 042/113] chore(version): update to version 10.7.3 --- CHANGELOG.md | 7 +++++++ CHANGELOG_DATA.json | 1 + dart_quill_delta/CHANGELOG.md | 7 +++++++ dart_quill_delta/pubspec.yaml | 2 +- flutter_quill_extensions/CHANGELOG.md | 7 +++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 7 +++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- quill_native_bridge/CHANGELOG.md | 7 +++++++ quill_native_bridge/pubspec.yaml | 2 +- 11 files changed, 41 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8da2a83ad..f29609c4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.3 + +- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` +- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3 + ## 10.7.2 ## What's Changed diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index e498c9fce..b6f4cb3d7 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.7.3": "- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions`\r\n- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3", "10.7.2": "## What's Changed\r\n* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258\r\n\r\nThis is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`.\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2", "10.7.1": "* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256\r\n* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1", "10.7.0": "* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0", diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index 8da2a83ad..f29609c4b 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.3 + +- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` +- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3 + ## 10.7.2 ## What's Changed diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index 33a04b208..b50175202 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 10.7.2 +version: 10.7.3 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 8da2a83ad..f29609c4b 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.3 + +- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` +- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3 + ## 10.7.2 ## What's Changed diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 30380f6bf..4ac344d25 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.7.2 +version: 10.7.3 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 8da2a83ad..f29609c4b 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.3 + +- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` +- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3 + ## 10.7.2 ## What's Changed diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index cd814c334..631d62543 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.7.2 +version: 10.7.3 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 6a69ccf72..f297d8f74 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.7.2 +version: 10.7.3 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/quill_native_bridge/CHANGELOG.md b/quill_native_bridge/CHANGELOG.md index 8da2a83ad..f29609c4b 100644 --- a/quill_native_bridge/CHANGELOG.md +++ b/quill_native_bridge/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.3 + +- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` +- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3 + ## 10.7.2 ## What's Changed diff --git a/quill_native_bridge/pubspec.yaml b/quill_native_bridge/pubspec.yaml index 799ddccb7..58228fcd9 100644 --- a/quill_native_bridge/pubspec.yaml +++ b/quill_native_bridge/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_native_bridge description: "An internal plugin for flutter_quill package to access platform-specific APIs" -version: 10.7.2 +version: 10.7.3 homepage: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ repository: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From a1bfa2daf968e7c38124dca1b9a1bc40a42f42bc Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 21 Sep 2024 15:45:11 +0300 Subject: [PATCH 043/113] chore(example): update pub.dev version of flutter_quill packages --- example/pubspec.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 572ced715..5c0c784fd 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -13,10 +13,10 @@ dependencies: cupertino_icons: ^1.0.6 # Flutter Quill Packages - flutter_quill: ^10.0.0 - dart_quill_delta: ^10.0.0 - flutter_quill_extensions: ^10.0.0 - flutter_quill_test: ^10.0.0 + flutter_quill: ^10.7.3 + dart_quill_delta: ^10.7.3 + flutter_quill_extensions: ^10.7.3 + flutter_quill_test: ^10.7.3 # Dart Packages path: ^1.8.3 equatable: ^2.0.5 From 0b78052ccacc7027577464966aae3e9198959429 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 21 Sep 2024 16:09:58 +0300 Subject: [PATCH 044/113] chore: deprecate QuillImageUtilities --- .../lib/src/common/utils/quill_image_utils.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flutter_quill_extensions/lib/src/common/utils/quill_image_utils.dart b/flutter_quill_extensions/lib/src/common/utils/quill_image_utils.dart index 435497106..20721d36a 100644 --- a/flutter_quill_extensions/lib/src/common/utils/quill_image_utils.dart +++ b/flutter_quill_extensions/lib/src/common/utils/quill_image_utils.dart @@ -10,6 +10,9 @@ typedef OnGenerateNewFileNameCallback = String Function( String fileExt, ); +@Deprecated( + 'QuillImageUtilities is no longer supported an will be removed in future releases.', +) class QuillImageUtilities { const QuillImageUtilities({ required this.document, From bb4e47d7e2459573b02bad3ffa75a17153867f7f Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 21 Sep 2024 18:09:06 +0300 Subject: [PATCH 045/113] chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled and local development (#2262) --- .github/workflows/build.yml | 3 -- .github/workflows/main.yml | 3 -- .github/workflows/publish.yml | 3 -- .gitignore | 3 -- .../pubspec_overrides.yaml.disabled | 3 -- .../pubspec_overrides.yaml.disabled | 3 -- pubspec_overrides.yaml.disabled | 7 ----- scripts/disable_local_dev.dart | 24 ---------------- scripts/enable_local_dev.dart | 28 ------------------- 9 files changed, 77 deletions(-) delete mode 100644 flutter_quill_extensions/pubspec_overrides.yaml.disabled delete mode 100644 flutter_quill_test/pubspec_overrides.yaml.disabled delete mode 100644 pubspec_overrides.yaml.disabled delete mode 100644 scripts/disable_local_dev.dart delete mode 100644 scripts/enable_local_dev.dart diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9163e982d..921f632fd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,9 +27,6 @@ jobs: - name: 📥 Install Flutter dependencies run: flutter pub get - - name: 🚧 Enable local development environment (use the local packages) - run: dart ./scripts/enable_local_dev.dart - - name: 🌐 Build Flutter Web Application run: flutter build web --release --verbose --dart-define=CI=true working-directory: ./example diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 33b01067f..f96c90d41 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,9 +27,6 @@ jobs: - name: 📥 Install Flutter dependencies run: flutter pub get - - name: 🚧 Enable local development environment (use the local packages) - run: dart ./scripts/enable_local_dev.dart - - name: 📦 Install dart_quill_delta dependencies run: flutter pub get -C dart_quill_delta diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 436c53e5d..941f0b094 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -40,9 +40,6 @@ jobs: - name: 📥 Install Flutter dependencies run: flutter pub get - - - name: 🚧 Enable local development environment (use the local packages) - run: dart ./scripts/enable_local_dev.dart # This is needed in order for the authentication to success # dart pub token add https://pub.dev --env-var PUB_TOKEN diff --git a/.gitignore b/.gitignore index 841758d28..ba9cc9155 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,3 @@ example/ios/Podfile.lock !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 pubspec.lock - -# For local development -pubspec_overrides.yaml \ No newline at end of file diff --git a/flutter_quill_extensions/pubspec_overrides.yaml.disabled b/flutter_quill_extensions/pubspec_overrides.yaml.disabled deleted file mode 100644 index 5593142ed..000000000 --- a/flutter_quill_extensions/pubspec_overrides.yaml.disabled +++ /dev/null @@ -1,3 +0,0 @@ -dependency_overrides: - flutter_quill: - path: ../ \ No newline at end of file diff --git a/flutter_quill_test/pubspec_overrides.yaml.disabled b/flutter_quill_test/pubspec_overrides.yaml.disabled deleted file mode 100644 index 5593142ed..000000000 --- a/flutter_quill_test/pubspec_overrides.yaml.disabled +++ /dev/null @@ -1,3 +0,0 @@ -dependency_overrides: - flutter_quill: - path: ../ \ No newline at end of file diff --git a/pubspec_overrides.yaml.disabled b/pubspec_overrides.yaml.disabled deleted file mode 100644 index abae944e4..000000000 --- a/pubspec_overrides.yaml.disabled +++ /dev/null @@ -1,7 +0,0 @@ -dependency_overrides: - flutter_quill_test: - path: ./flutter_quill_test - dart_quill_delta: - path: ./dart_quill_delta - quill_native_bridge: - path: ./quill_native_bridge \ No newline at end of file diff --git a/scripts/disable_local_dev.dart b/scripts/disable_local_dev.dart deleted file mode 100644 index 80136cee0..000000000 --- a/scripts/disable_local_dev.dart +++ /dev/null @@ -1,24 +0,0 @@ -// ignore_for_file: avoid_print - -import 'dart:io' show File; - -import 'package:path/path.dart' as path; - -import './pub_get.dart' as pub_get show main; -import 'packages.dart' show repoPackages; - -Future main(List args) async { - for (final package in repoPackages) { - await disable(packageDirectoryPath: package); - } - await pub_get.main([]); - print('Local development for all libraries has been disabled'); -} - -Future disable({required String packageDirectoryPath}) async { - final pubspecOverridesFile = - File(path.join(packageDirectoryPath, 'pubspec_overrides.yaml')); - if (await pubspecOverridesFile.exists()) { - await pubspecOverridesFile.delete(); - } -} diff --git a/scripts/enable_local_dev.dart b/scripts/enable_local_dev.dart deleted file mode 100644 index a41c42518..000000000 --- a/scripts/enable_local_dev.dart +++ /dev/null @@ -1,28 +0,0 @@ -// ignore_for_file: avoid_print - -import 'dart:io' show File; - -import 'package:path/path.dart' as path; - -import './pub_get.dart' as pub_get show main; -import 'packages.dart' show repoPackages; - -Future main(List args) async { - for (final package in repoPackages) { - await enable(packageDirectoryPath: package); - } - await pub_get.main([]); - print('Local development for all libraries has been enabled'); -} - -Future enable({required String packageDirectoryPath}) async { - final pubspecOverridesFile = - File(path.join(packageDirectoryPath, 'pubspec_overrides.yaml')); - final pubspecOverridesDisabledFile = - File(path.join(packageDirectoryPath, 'pubspec_overrides.yaml.disabled')); - if (!(await pubspecOverridesDisabledFile.exists())) { - print('$packageDirectoryPath does not support local development mode.'); - return; - } - await pubspecOverridesDisabledFile.copy(pubspecOverridesFile.path); -} From 1e989d2bc4a3ca3f478c2dec8771ee1cde5afab2 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 21 Sep 2024 18:45:27 +0300 Subject: [PATCH 046/113] ci: remove quill_native_bridge from automated publishing workflow (#2263) --- .github/workflows/main.yml | 3 --- .github/workflows/publish.yml | 3 --- 2 files changed, 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f96c90d41..7260bad4e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,9 +36,6 @@ jobs: - name: 📦 Install flutter_quill_test dependencies run: flutter pub get -C flutter_quill_test - - name: 📦 Install quill_native_bridge dependencies - run: flutter pub get -C quill_native_bridge - - name: 🔍 Run Flutter analysis run: flutter analyze diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 941f0b094..ad73c5823 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -105,6 +105,3 @@ jobs: run: flutter pub publish --force working-directory: ./flutter_quill_test/ - - name: 📤 Publish quill_native_bridge - run: flutter pub publish --force - working-directory: ./quill_native_bridge/ From 73dc05f32b4a8ca1095f24ccde7264e593fe16f1 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 21 Sep 2024 19:02:15 +0300 Subject: [PATCH 047/113] chore: remove quill_native_bridge from rootPackages in scripts to ensure that CHANGELOG.md and version will not be updated --- scripts/packages.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/packages.dart b/scripts/packages.dart index 229074f43..0ad09cd6e 100644 --- a/scripts/packages.dart +++ b/scripts/packages.dart @@ -4,5 +4,4 @@ const repoPackages = [ './dart_quill_delta', './flutter_quill_extensions', './flutter_quill_test', - './quill_native_bridge' ]; From 0eb4987e08c90118ab94904a2b4da5695b4f56d8 Mon Sep 17 00:00:00 2001 From: singerdmx Date: Sat, 21 Sep 2024 18:46:14 +0000 Subject: [PATCH 048/113] chore(version): update to version 10.7.4 --- CHANGELOG.md | 8 ++++++++ CHANGELOG_DATA.json | 1 + dart_quill_delta/CHANGELOG.md | 8 ++++++++ dart_quill_delta/pubspec.yaml | 2 +- example/macos/Flutter/GeneratedPluginRegistrant.swift | 2 ++ flutter_quill_extensions/CHANGELOG.md | 8 ++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 8 ++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 10 files changed, 39 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f29609c4b..86eaa7311 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.4 + +* chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262 +* ci: remove quill_native_bridge from automated publishing workflow by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2263 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.3...v10.7.4 + ## 10.7.3 - Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index b6f4cb3d7..9f8c8f892 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.7.4": "* chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262\r\n* ci: remove quill_native_bridge from automated publishing workflow by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2263\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.3...v10.7.4", "10.7.3": "- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions`\r\n- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3", "10.7.2": "## What's Changed\r\n* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258\r\n\r\nThis is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`.\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2", "10.7.1": "* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256\r\n* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1", diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index f29609c4b..86eaa7311 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.4 + +* chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262 +* ci: remove quill_native_bridge from automated publishing workflow by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2263 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.3...v10.7.4 + ## 10.7.3 - Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index b50175202..f84960f9b 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 10.7.3 +version: 10.7.4 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index eabf85a3e..c51d61035 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -12,6 +12,7 @@ import flutter_inappwebview_macos import gal import irondash_engine_context import path_provider_foundation +import quill_native_bridge import share_plus import sqflite import super_native_extensions @@ -26,6 +27,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin")) IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + QuillNativeBridgePlugin.register(with: registry.registrar(forPlugin: "QuillNativeBridgePlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin")) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index f29609c4b..86eaa7311 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.4 + +* chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262 +* ci: remove quill_native_bridge from automated publishing workflow by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2263 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.3...v10.7.4 + ## 10.7.3 - Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 4ac344d25..063b2097e 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.7.3 +version: 10.7.4 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index f29609c4b..86eaa7311 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.4 + +* chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262 +* ci: remove quill_native_bridge from automated publishing workflow by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2263 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.3...v10.7.4 + ## 10.7.3 - Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 631d62543..934b5b3e2 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.7.3 +version: 10.7.4 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index f297d8f74..e00dddece 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.7.3 +version: 10.7.4 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 4ce5bc8430f462381ddb7544324ea29f03a8e6b5 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sun, 22 Sep 2024 00:40:58 +0300 Subject: [PATCH 049/113] fix(ci): add flutter pub get step for quill_native_bridge to fix failure in #2264 (#2265) --- .github/workflows/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7260bad4e..f96c90d41 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,6 +36,9 @@ jobs: - name: 📦 Install flutter_quill_test dependencies run: flutter pub get -C flutter_quill_test + - name: 📦 Install quill_native_bridge dependencies + run: flutter pub get -C quill_native_bridge + - name: 🔍 Run Flutter analysis run: flutter analyze From 40fd709b1666408d7825593611c5876940f966f9 Mon Sep 17 00:00:00 2001 From: Cat <114286961+CatHood0@users.noreply.github.com> Date: Sat, 21 Sep 2024 22:27:10 -0400 Subject: [PATCH 050/113] revert: "Resolved issue with broken IME composing rect in Windows desktop" (#2266) * revert: Resolved issue with broken IME composing rect in Windows desktop * Chore: dart format --------- Co-authored-by: CatHood0 --- .../raw_editor_state_text_input_client_mixin.dart | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart b/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart index 99f99a7b4..70336b2cf 100644 --- a/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart +++ b/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart @@ -112,19 +112,9 @@ mixin RawEditorStateTextInputClientMixin on EditorState _textInputConnection!.show(); } - TextRange _getComposingRange() { - if (_lastKnownRemoteTextEditingValue != null && - _lastKnownRemoteTextEditingValue?.composing.isValid == true) { - return _lastKnownRemoteTextEditingValue!.composing; - } else if (textEditingValue.composing.isValid == true) { - return textEditingValue.composing; - } else { - return widget.controller.selection; - } - } - void _updateComposingRectIfNeeded() { - final composingRange = _getComposingRange(); + final composingRange = _lastKnownRemoteTextEditingValue?.composing ?? + textEditingValue.composing; if (hasConnection) { assert(mounted); final offset = composingRange.isValid ? composingRange.start : 0; From 4c23d98bc8670381951cfac525ed93e70d279bc6 Mon Sep 17 00:00:00 2001 From: singerdmx Date: Sun, 22 Sep 2024 02:28:16 +0000 Subject: [PATCH 051/113] chore(version): update to version 10.7.5 --- CHANGELOG.md | 8 ++++++++ CHANGELOG_DATA.json | 1 + dart_quill_delta/CHANGELOG.md | 8 ++++++++ dart_quill_delta/pubspec.yaml | 2 +- flutter_quill_extensions/CHANGELOG.md | 8 ++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 8 ++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 9 files changed, 37 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86eaa7311..75e834096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.5 + +* fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265 +* revert: "Resolved issue with broken IME composing rect in Windows desktop" by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2266 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.4...v10.7.5 + ## 10.7.4 * chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262 diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index 9f8c8f892..36af27f37 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.7.5": "* fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265\r\n* revert: \"Resolved issue with broken IME composing rect in Windows desktop\" by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2266\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.4...v10.7.5", "10.7.4": "* chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262\r\n* ci: remove quill_native_bridge from automated publishing workflow by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2263\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.3...v10.7.4", "10.7.3": "- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions`\r\n- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3", "10.7.2": "## What's Changed\r\n* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258\r\n\r\nThis is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`.\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2", diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index 86eaa7311..75e834096 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.5 + +* fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265 +* revert: "Resolved issue with broken IME composing rect in Windows desktop" by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2266 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.4...v10.7.5 + ## 10.7.4 * chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262 diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index f84960f9b..f24fd9788 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 10.7.4 +version: 10.7.5 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 86eaa7311..75e834096 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.5 + +* fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265 +* revert: "Resolved issue with broken IME composing rect in Windows desktop" by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2266 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.4...v10.7.5 + ## 10.7.4 * chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 063b2097e..74b682f3e 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.7.4 +version: 10.7.5 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 86eaa7311..75e834096 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.7.5 + +* fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265 +* revert: "Resolved issue with broken IME composing rect in Windows desktop" by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2266 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.4...v10.7.5 + ## 10.7.4 * chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 934b5b3e2..37ccfc435 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.7.4 +version: 10.7.5 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index e00dddece..9f06a144b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.7.4 +version: 10.7.5 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From a4f69a78258abed124d2d8d199c04b442312032a Mon Sep 17 00:00:00 2001 From: Luis Date: Sun, 22 Sep 2024 00:07:54 -0400 Subject: [PATCH 052/113] Comment Typos fix (#2267) Co-authored-by: Luis Bonilla --- lib/src/toolbar/config/base_button_configurations.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/toolbar/config/base_button_configurations.dart b/lib/src/toolbar/config/base_button_configurations.dart index 1c2acf541..c06255e56 100644 --- a/lib/src/toolbar/config/base_button_configurations.dart +++ b/lib/src/toolbar/config/base_button_configurations.dart @@ -38,7 +38,7 @@ class QuillToolbarBaseButtonExtraOptions extends Equatable { } /// The [T] is the options for the button, usually should refresnce itself -/// it's used in [childBuilder] so the developer can custmize this when using it +/// it's used in [childBuilder] so the developer can customize this when using it /// The [I] is extra options for the button, usually for it's state @immutable class QuillToolbarBaseButtonOptions extends Equatable { @@ -90,7 +90,7 @@ class QuillToolbarBaseButtonOptions extends Equatable { /// Use custom theme final QuillIconTheme? iconTheme; - /// If you want to dispaly a differnet widget based using a builder + /// If you want to display a different widget based using a builder final QuillToolbarButtonOptionsChildBuilder childBuilder; @override From 0f03135914a89d4264704f232df07cb22e71dab2 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sun, 22 Sep 2024 20:08:15 +0300 Subject: [PATCH 053/113] docs: add important note for contributors before introducing new features (#2269) --- CONTRIBUTING.md | 9 ++++++++- README.md | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f5183b37f..56f899f86 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,13 @@ # 🌱 Contributing -First, we would like to thank you for your time and efforts on this project, we appreciate it +First, we would like to thank you for your time and efforts on this project, we appreciate it. + +> [!IMPORTANT] +> At this time, we prioritize bug fixes and code quality improvements over new features. +> Please refrain from submitting large changes to add new features, as they might +> not be merged, and exceptions may made. +> We encourage you to create an issue or reach out beforehand, +> explaining your proposed changes and their rationale for a higher chance of acceptance. Thank you! If you don't have anything specific in mind to improve or fix, you can take a look at the issues tab or take a look at the todos of the project, they all start with `TODO:` so you can search in your IDE or use the todos tab in the IDE. diff --git a/README.md b/README.md index b48375331..5ca90e56e 100644 --- a/README.md +++ b/README.md @@ -314,6 +314,13 @@ Notice that currently, the support for testing is limited. ## 🤝 Contributing +> [!IMPORTANT] +> At this time, we prioritize bug fixes and code quality improvements over new features. +> Please refrain from submitting large changes to add new features, as they might +> not be merged, and exceptions may made. +> We encourage you to create an issue or reach out beforehand, +> explaining your proposed changes and their rationale for a higher chance of acceptance. Thank you! + We greatly appreciate your time and effort. To keep the project consistent and maintainable, we have a few guidelines that we ask all contributors to follow. From 1690bff1ab155ccd6bd3c993256e4e2765e1d230 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sun, 22 Sep 2024 20:17:48 +0300 Subject: [PATCH 054/113] docs: remove table support note in README of flutter_quill_extensions due to #2254 --- flutter_quill_extensions/README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index 235a8b35b..a7708e7b4 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -1,11 +1,7 @@ # Flutter Quill Extensions An extension for [flutter_quill](https://pub.dev/packages/flutter_quill) -to support embedding widgets images, formulas, videos, and tables. - -> The support for tables is currently limited and underdevelopment, more changes are expected to arrive. We are actively -> working on enhancing its functionality and usability. We appreciate your feedback as it is invaluable in helping us -> refine and expand this feature. +to support embedding widgets images, formulas, videos. ## 📚 Table of Contents @@ -296,4 +292,4 @@ We greatly appreciate your time and effort. To keep the project consistent and maintainable, we have a few guidelines that we ask all contributors to follow. These guidelines help ensure that everyone can understand and work with the code easier. -See [Contributing](../CONTRIBUTING.md) for more details. \ No newline at end of file +See [Contributing](../CONTRIBUTING.md) for more details. From 9cf64d2a520e9afe7f79c8f9133c82873c383ea1 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sun, 22 Sep 2024 20:18:36 +0300 Subject: [PATCH 055/113] docs: add 'and' before videos in extensions package --- flutter_quill_extensions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index a7708e7b4..891f0232e 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -1,7 +1,7 @@ # Flutter Quill Extensions An extension for [flutter_quill](https://pub.dev/packages/flutter_quill) -to support embedding widgets images, formulas, videos. +to support embedding widgets images, formulas, and videos. ## 📚 Table of Contents From c8bd92e7a26856d3175b7a534e906312ba516d9d Mon Sep 17 00:00:00 2001 From: Ellet Date: Mon, 23 Sep 2024 23:50:30 +0300 Subject: [PATCH 056/113] docs(readme): add 'Breaking Changes' section (#2275) --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 5ca90e56e..d314ce643 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ You can join our [Slack Group] for discussion. - [📦 Installation](#-installation) - [🛠 Platform Specific Configurations](#-platform-specific-configurations) - [🚀 Usage](#-usage) +- [💥 Breaking Changes](#-breaking-changes) - [🔤 Input / Output](#-input--output) - [⚙️ Configurations](#️-configurations) - [📦 Embed Blocks](#-embed-blocks) @@ -158,6 +159,23 @@ void dispose() { Check out [Sample Page] for more advanced usage. +## 💥 Breaking Changes + +- APIs marked with [`@experimental`](https://api.flutter.dev/flutter/meta/experimental-constant.html) +are subject to change or removal at any time and should be used with caution, +as they may be altered even in minor versions. + +- APIs marked with [`@internal`](https://api.flutter.dev/flutter/meta/internal-constant.html) +and [`@visibleForTesting`](https://api.flutter.dev/flutter/meta/visibleForTesting-constant.html) are not intended for +public use and should be avoided entirely. + +- The `package:flutter_quill/flutter_quill_internal.dart` expose internal APIs +to be used by other related packages and should be avoided when possible. + +We make every effort to ensure internal APIs are not exported by default. Use experimental features at your own discretion. + +We recommend checking the `CHANGELOG.md` or release notes for each update to stay informed. + ## 🔤 Input / Output This library uses [Quill Delta](https://quilljs.com/docs/delta/) From abbe9ce8dc13f6933dedfd629ba03c20823ae665 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 24 Sep 2024 20:01:35 +0300 Subject: [PATCH 057/113] chore(example): update macOS Podfile.lock --- example/macos/Podfile.lock | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index 72d8d70f9..2d04e0a53 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -18,6 +18,8 @@ PODS: - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS + - quill_native_bridge (0.0.1): + - FlutterMacOS - share_plus (0.0.1): - FlutterMacOS - sqflite (0.0.3): @@ -40,6 +42,7 @@ DEPENDENCIES: - gal (from `Flutter/ephemeral/.symlinks/plugins/gal/darwin`) - irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) + - quill_native_bridge (from `Flutter/ephemeral/.symlinks/plugins/quill_native_bridge/macos`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`) - super_native_extensions (from `Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos`) @@ -67,6 +70,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos path_provider_foundation: :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin + quill_native_bridge: + :path: Flutter/ephemeral/.symlinks/plugins/quill_native_bridge/macos share_plus: :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos sqflite: @@ -88,6 +93,7 @@ SPEC CHECKSUMS: irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478 OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 + quill_native_bridge: 1a3a4bfab7cbe4ed0232a17d8aae201a3ce6d302 share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3 From e7e6b3fd8538ff1767cd8b8cf7f15aee16177133 Mon Sep 17 00:00:00 2001 From: agata Date: Wed, 25 Sep 2024 16:40:43 +0900 Subject: [PATCH 058/113] Fix: Resolved issue with broken IME composing rect in Windows desktop app (#2282) - Fixed issue where the composing rect would break during IME conversion. - When the composing region is unknown, it now avoids calling setComposingRect on TextInputConnection. --- .../raw_editor_state_text_input_client_mixin.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart b/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart index 70336b2cf..74a6f520c 100644 --- a/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart +++ b/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart @@ -117,10 +117,12 @@ mixin RawEditorStateTextInputClientMixin on EditorState textEditingValue.composing; if (hasConnection) { assert(mounted); - final offset = composingRange.isValid ? composingRange.start : 0; - final composingRect = - renderEditor.getLocalRectForCaret(TextPosition(offset: offset)); - _textInputConnection!.setComposingRect(composingRect); + if (composingRange.isValid) { + final offset = composingRange.start; + final composingRect = + renderEditor.getLocalRectForCaret(TextPosition(offset: offset)); + _textInputConnection!.setComposingRect(composingRect); + } SchedulerBinding.instance .addPostFrameCallback((_) => _updateComposingRectIfNeeded()); } From b5899725845fbcaab73a8e91952c723dbe11910e Mon Sep 17 00:00:00 2001 From: singerdmx Date: Wed, 25 Sep 2024 07:41:54 +0000 Subject: [PATCH 059/113] chore(version): update to version 10.7.6 --- CHANGELOG.md | 12 ++++++++++++ CHANGELOG_DATA.json | 1 + dart_quill_delta/CHANGELOG.md | 12 ++++++++++++ dart_quill_delta/pubspec.yaml | 2 +- .../windows/flutter/generated_plugin_registrant.cc | 3 +++ example/windows/flutter/generated_plugins.cmake | 1 + flutter_quill_extensions/CHANGELOG.md | 12 ++++++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 12 ++++++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 11 files changed, 57 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75e834096..88ecee633 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. +## 10.7.6 + +* Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267 +* docs: add important note for contributors before introducing new features by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2269 +* docs(readme): add 'Breaking Changes' section by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2275 +* Fix: Resolved issue with broken IME composing rect in Windows desktop(re-implementation) by @agata in https://github.com/singerdmx/flutter-quill/pull/2282 + +## New Contributors +* @Luismi74 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2267 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.5...v10.7.6 + ## 10.7.5 * fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265 diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index 36af27f37..dd145cb0e 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.7.6": "* Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267\r\n* docs: add important note for contributors before introducing new features by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2269\r\n* docs(readme): add 'Breaking Changes' section by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2275\r\n* Fix: Resolved issue with broken IME composing rect in Windows desktop(re-implementation) by @agata in https://github.com/singerdmx/flutter-quill/pull/2282\r\n\r\n## New Contributors\r\n* @Luismi74 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2267\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.5...v10.7.6", "10.7.5": "* fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265\r\n* revert: \"Resolved issue with broken IME composing rect in Windows desktop\" by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2266\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.4...v10.7.5", "10.7.4": "* chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262\r\n* ci: remove quill_native_bridge from automated publishing workflow by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2263\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.3...v10.7.4", "10.7.3": "- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions`\r\n- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3", diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index 75e834096..88ecee633 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. +## 10.7.6 + +* Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267 +* docs: add important note for contributors before introducing new features by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2269 +* docs(readme): add 'Breaking Changes' section by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2275 +* Fix: Resolved issue with broken IME composing rect in Windows desktop(re-implementation) by @agata in https://github.com/singerdmx/flutter-quill/pull/2282 + +## New Contributors +* @Luismi74 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2267 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.5...v10.7.6 + ## 10.7.5 * fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265 diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index f24fd9788..6c759668f 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 10.7.5 +version: 10.7.6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc index 084810413..8e3614f6f 100644 --- a/example/windows/flutter/generated_plugin_registrant.cc +++ b/example/windows/flutter/generated_plugin_registrant.cc @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -19,6 +20,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("DesktopDropPlugin")); FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); + FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi")); GalPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("GalPluginCApi")); IrondashEngineContextPluginCApiRegisterWithRegistrar( diff --git a/example/windows/flutter/generated_plugins.cmake b/example/windows/flutter/generated_plugins.cmake index f568d1445..a10959609 100644 --- a/example/windows/flutter/generated_plugins.cmake +++ b/example/windows/flutter/generated_plugins.cmake @@ -5,6 +5,7 @@ list(APPEND FLUTTER_PLUGIN_LIST desktop_drop file_selector_windows + flutter_inappwebview_windows gal irondash_engine_context share_plus diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 75e834096..88ecee633 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. +## 10.7.6 + +* Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267 +* docs: add important note for contributors before introducing new features by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2269 +* docs(readme): add 'Breaking Changes' section by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2275 +* Fix: Resolved issue with broken IME composing rect in Windows desktop(re-implementation) by @agata in https://github.com/singerdmx/flutter-quill/pull/2282 + +## New Contributors +* @Luismi74 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2267 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.5...v10.7.6 + ## 10.7.5 * fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 74b682f3e..d30ea0100 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.7.5 +version: 10.7.6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 75e834096..88ecee633 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. +## 10.7.6 + +* Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267 +* docs: add important note for contributors before introducing new features by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2269 +* docs(readme): add 'Breaking Changes' section by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2275 +* Fix: Resolved issue with broken IME composing rect in Windows desktop(re-implementation) by @agata in https://github.com/singerdmx/flutter-quill/pull/2282 + +## New Contributors +* @Luismi74 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2267 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.5...v10.7.6 + ## 10.7.5 * fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 37ccfc435..6d005cfa8 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.7.5 +version: 10.7.6 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 9f06a144b..1271aa490 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.7.5 +version: 10.7.6 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 740c0cde7d86464f1773648ed504b28238a64101 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 25 Sep 2024 13:29:26 +0300 Subject: [PATCH 060/113] fix: update version range of quill_native_bridge to avoid using latest version of the package (#2283) * fix: set quill_native_bridge version range from 10.5.14 to 10.6.2 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 1271aa490..fae56e36f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,7 +62,7 @@ dependencies: # Plugins url_launcher: ^6.2.4 flutter_keyboard_visibility: ^6.0.0 - quill_native_bridge: ^10.5.14 + quill_native_bridge: '>=10.5.14 <=10.6.2' dev_dependencies: flutter_lints: ^4.0.0 From 45b6618f350ae2ca8b3f7b159fea2bf1d346b183 Mon Sep 17 00:00:00 2001 From: EchoEllet Date: Wed, 25 Sep 2024 10:32:12 +0000 Subject: [PATCH 061/113] chore(version): update to version 10.7.7 --- CHANGELOG.md | 7 +++++++ CHANGELOG_DATA.json | 1 + dart_quill_delta/CHANGELOG.md | 7 +++++++ dart_quill_delta/pubspec.yaml | 2 +- example/macos/Flutter/GeneratedPluginRegistrant.swift | 2 -- flutter_quill_extensions/CHANGELOG.md | 7 +++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 7 +++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 10 files changed, 33 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88ecee633..c7a579c5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.7 + +This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230) + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.6...v10.7.7 + ## 10.7.6 * Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267 diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index dd145cb0e..b5afddc49 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.7.7": "This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230)\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.6...v10.7.7", "10.7.6": "* Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267\r\n* docs: add important note for contributors before introducing new features by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2269\r\n* docs(readme): add 'Breaking Changes' section by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2275\r\n* Fix: Resolved issue with broken IME composing rect in Windows desktop(re-implementation) by @agata in https://github.com/singerdmx/flutter-quill/pull/2282\r\n\r\n## New Contributors\r\n* @Luismi74 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2267\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.5...v10.7.6", "10.7.5": "* fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265\r\n* revert: \"Resolved issue with broken IME composing rect in Windows desktop\" by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2266\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.4...v10.7.5", "10.7.4": "* chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262\r\n* ci: remove quill_native_bridge from automated publishing workflow by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2263\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.3...v10.7.4", diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index 88ecee633..c7a579c5e 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.7 + +This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230) + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.6...v10.7.7 + ## 10.7.6 * Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267 diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index 6c759668f..de594c1df 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 10.7.6 +version: 10.7.7 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index c51d61035..eabf85a3e 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -12,7 +12,6 @@ import flutter_inappwebview_macos import gal import irondash_engine_context import path_provider_foundation -import quill_native_bridge import share_plus import sqflite import super_native_extensions @@ -27,7 +26,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin")) IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) - QuillNativeBridgePlugin.register(with: registry.registrar(forPlugin: "QuillNativeBridgePlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin")) diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 88ecee633..c7a579c5e 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.7 + +This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230) + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.6...v10.7.7 + ## 10.7.6 * Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index d30ea0100..3763f76fd 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.7.6 +version: 10.7.7 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 88ecee633..c7a579c5e 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.7.7 + +This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230) + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.6...v10.7.7 + ## 10.7.6 * Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 6d005cfa8..2661a3b76 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.7.6 +version: 10.7.7 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index fae56e36f..9cc2b0626 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.7.6 +version: 10.7.7 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 5d2b74c51fd6f1096ed08f58752e49b02e9e2689 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 25 Sep 2024 20:01:05 +0300 Subject: [PATCH 062/113] fix(extensions)!: drop support for YouTube iframeView for non-web platforms, remove youtube_player_flutter dependency, throw warnings for anything related to YoutubeVideoApp in development mode (#2286) * fix: drop support for YouTube iframeView for non-web platforms, throw warnings for anything related to YoutubeVideoApp in development mode --- .../lib/screens/quill/my_quill_editor.dart | 13 +- example/macos/Podfile.lock | 6 - flutter_quill_extensions/README.md | 5 +- .../lib/src/common/utils/utils.dart | 4 + .../video/models/video_configurations.dart | 59 ++++++++- .../models/video_web_configurations.dart | 1 + .../models/youtube_video_support_mode.dart | 37 +++++- .../lib/src/editor/video/video_embed.dart | 27 ++++- .../lib/src/editor/video/video_web_embed.dart | 7 +- .../video/widgets/youtube_video_app.dart | 112 ++++++++++++------ .../src/editor/video/youtube_video_url.dart | 32 +++++ flutter_quill_extensions/pubspec.yaml | 2 +- 12 files changed, 246 insertions(+), 59 deletions(-) create mode 100644 flutter_quill_extensions/lib/src/editor/video/youtube_video_url.dart diff --git a/example/lib/screens/quill/my_quill_editor.dart b/example/lib/screens/quill/my_quill_editor.dart index ad5eb13e5..c9fb632c8 100644 --- a/example/lib/screens/quill/my_quill_editor.dart +++ b/example/lib/screens/quill/my_quill_editor.dart @@ -128,11 +128,14 @@ class MyQuillEditor extends StatelessWidget { }, ), videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations( - // Loading YouTube videos on Desktop is not supported yet - // when using iframe platform view - youtubeVideoSupportMode: isDesktopApp - ? YoutubeVideoSupportMode.customPlayerWithDownloadUrl - : YoutubeVideoSupportMode.iframeView, + customVideoBuilder: (videoUrl, readOnly) { + // Example: Check for YouTube Video URL and return your + // YouTube video widget here. + + // Otherwise return null to fallback to the defualt logic + return null; + }, + ignoreYouTubeSupport: true, ), )), TimeStampEmbedBuilderWidget(), diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index 2d04e0a53..72d8d70f9 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -18,8 +18,6 @@ PODS: - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - - quill_native_bridge (0.0.1): - - FlutterMacOS - share_plus (0.0.1): - FlutterMacOS - sqflite (0.0.3): @@ -42,7 +40,6 @@ DEPENDENCIES: - gal (from `Flutter/ephemeral/.symlinks/plugins/gal/darwin`) - irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - - quill_native_bridge (from `Flutter/ephemeral/.symlinks/plugins/quill_native_bridge/macos`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`) - super_native_extensions (from `Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos`) @@ -70,8 +67,6 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos path_provider_foundation: :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin - quill_native_bridge: - :path: Flutter/ephemeral/.symlinks/plugins/quill_native_bridge/macos share_plus: :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos sqflite: @@ -93,7 +88,6 @@ SPEC CHECKSUMS: irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478 OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 - quill_native_bridge: 1a3a4bfab7cbe4ed0232a17d8aae201a3ce6d302 share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3 diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index 891f0232e..8a6ab3388 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -50,10 +50,7 @@ The package uses the following plugins: platform-specific setup. 2. [`image_picker`](https://pub.dev/packages/image_picker) for picking images. See the [Installation](https://pub.dev/packages/image_picker#installation) section. -3. [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter) which - uses [`flutter_inappwebview`](https://pub.dev/packages/flutter_inappwebview) which has a requirement setup on web. - See the [Installation - Web support](https://pub.dev/packages/flutter_inappwebview#installation---web-support). -4. [`super_clipboard`](https://pub.dev/packages/super_clipboard) which needs some setup on Android only, it's used to +3. [`super_clipboard`](https://pub.dev/packages/super_clipboard) which needs some setup on Android only, it's used to support copying images and pasting them into editor, it's also required to support rich text pasting feature on non-web platforms, Open the [Android Support](https://pub.dev/packages/super_clipboard#android-support) page for instructions. diff --git a/flutter_quill_extensions/lib/src/common/utils/utils.dart b/flutter_quill_extensions/lib/src/common/utils/utils.dart index 1dbf8079e..f8fa05f4f 100644 --- a/flutter_quill_extensions/lib/src/common/utils/utils.dart +++ b/flutter_quill_extensions/lib/src/common/utils/utils.dart @@ -25,6 +25,10 @@ bool isImageBase64(String imageUrl) { return !isHttpBasedUrl(imageUrl) && isBase64(imageUrl); } +@Deprecated( + 'Will be removed in future releases. See https://github.com/singerdmx/flutter-quill/issues/2284' + ' and https://github.com/singerdmx/flutter-quill/issues/2276', +) bool isYouTubeUrl(String videoUrl) { try { final uri = Uri.parse(videoUrl); diff --git a/flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart b/flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart index cecc1c2e6..ba1ac23c7 100644 --- a/flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart +++ b/flutter_quill_extensions/lib/src/editor/video/models/video_configurations.dart @@ -1,5 +1,5 @@ -import 'package:flutter/widgets.dart' show GlobalKey; -import 'package:meta/meta.dart' show immutable; +import 'package:flutter/widgets.dart' show GlobalKey, Widget; +import 'package:meta/meta.dart' show experimental, immutable; import 'youtube_video_support_mode.dart'; @@ -7,7 +7,16 @@ import 'youtube_video_support_mode.dart'; class QuillEditorVideoEmbedConfigurations { const QuillEditorVideoEmbedConfigurations({ this.onVideoInit, - this.youtubeVideoSupportMode = YoutubeVideoSupportMode.iframeView, + @Deprecated( + 'Loading youtube videos is no longer built-in feature of flutter_quill_extensions.\n' + 'See https://github.com/singerdmx/flutter-quill/issues/2284.\n' + 'Try to use the experimental `customVideoBuilder` property to implement\n' + 'your own YouTube logic using packages such as ' + 'https://pub.dev/packages/youtube_video_player or https://pub.dev/packages/youtube_player_flutter', + ) + this.youtubeVideoSupportMode = YoutubeVideoSupportMode.disabled, + this.ignoreYouTubeSupport = false, + this.customVideoBuilder, }); /// [onVideoInit] is a callback function that gets triggered when @@ -27,5 +36,49 @@ class QuillEditorVideoEmbedConfigurations { /// Specifies how YouTube videos should be loaded if the video URL /// is YouTube video. + @Deprecated( + 'Loading youtube videos is no longer built-in feature of flutter_quill_extensions.\n' + 'See https://github.com/singerdmx/flutter-quill/issues/2284.\n' + 'Try to use the experimental `customVideoBuilder` property to implement\n' + 'your own YouTube logic using packages such as ' + 'https://pub.dev/packages/youtube_video_player or https://pub.dev/packages/youtube_player_flutter', + ) final YoutubeVideoSupportMode youtubeVideoSupportMode; + + /// Pass `true` to ignore anything related to YouTube which will disable + /// This functionality is without any warnings. + /// + /// Making it `true`, means that the video embed widget will no longer + /// check for the video URL and expect it a valid and a standrad video URL. + /// + /// This property will be removed in future releases once YouTube support is + /// removed. + /// + /// Use [customVideoBuilder] to load youtube videos. + @experimental + @Deprecated( + 'Will be removed in future releases. Exist to allow users to ignore warnings.', + ) + final bool ignoreYouTubeSupport; + + /// [customVideoBuilder] is a callback function that receives the + /// video URL and a read-only flag. This allows users to define + /// their own logic for rendering video widgets, enabling support + /// for various video platforms, such as YouTube. + /// + /// Example usage: + /// ```dart + /// customVideoBuilder: (videoUrl, readOnly) { + /// // Return `null` to fallback to defualt logic of QuillEditorVideoEmbedBuilder + /// + /// // Return a custom video widget based on the videoUrl + /// return CustomVideoWidget(videoUrl: videoUrl, readOnly: readOnly); + /// }, + /// ``` + /// + /// It's a quick solution as response to https://github.com/singerdmx/flutter-quill/issues/2284 + /// + /// **Might be removed or changed in future releases.** + @experimental + final Widget? Function(String videoUrl, bool readOnly)? customVideoBuilder; } diff --git a/flutter_quill_extensions/lib/src/editor/video/models/video_web_configurations.dart b/flutter_quill_extensions/lib/src/editor/video/models/video_web_configurations.dart index 26d7f1108..084cb1939 100644 --- a/flutter_quill_extensions/lib/src/editor/video/models/video_web_configurations.dart +++ b/flutter_quill_extensions/lib/src/editor/video/models/video_web_configurations.dart @@ -7,5 +7,6 @@ class QuillEditorWebVideoEmbedConfigurations { this.constraints, }); + @Deprecated('This property is no longer used.') final BoxConstraints? constraints; } diff --git a/flutter_quill_extensions/lib/src/editor/video/models/youtube_video_support_mode.dart b/flutter_quill_extensions/lib/src/editor/video/models/youtube_video_support_mode.dart index d66285ce2..0884c6741 100644 --- a/flutter_quill_extensions/lib/src/editor/video/models/youtube_video_support_mode.dart +++ b/flutter_quill_extensions/lib/src/editor/video/models/youtube_video_support_mode.dart @@ -1,8 +1,19 @@ -/// Enum represents the different modes for handling YouTube video support. +import 'package:meta/meta.dart'; + +/// **Will be removed soon in future releases**. +@experimental +@Deprecated( + 'YouTube video support will be removed soon and completely in the next releases.', +) enum YoutubeVideoSupportMode { + /// **Will be removed soon in future releases**. /// Disable loading of YouTube videos. + /// **Will be removed soon in future releases**. + @Deprecated('Loading YouTube videos is already disabled by default.') disabled, + /// **Will be removed soon in future releases**. + /// /// Load the video using the official YouTube IFrame API. /// See [YouTube IFrame API](https://developers.google.com/youtube/iframe_api_reference) for more details. /// @@ -10,10 +21,34 @@ enum YoutubeVideoSupportMode { /// The WebView might not be supported on Desktop and will throw an exception /// /// See [Flutter InAppWebview Support for Flutter Desktop](https://github.com/pichillilorenzo/flutter_inappwebview/issues/460) + /// + /// **Important**: We had to remove [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) + /// and [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) + /// as non breaking change since most users are unable to build the project, + /// preventing them from using + /// + /// **Will be removed soon in future releases**. + @Deprecated( + 'This functionality has been removed to fix build failure issues. See https://github.com/singerdmx/flutter-quill/issues/2284 for discussion.', + ) iframeView, + /// **Will be removed soon in future releases**. + /// /// Load the video using a custom video player by fetching the YouTube video URL. /// Note: This might violate YouTube's terms of service. /// See [YouTube Terms of Service](https://www.youtube.com/static?template=terms) for more details. + /// + /// **WARNING**: We highly suggest to not use this solution, + /// can cause issues with YouTube Terms of Service and require a extra dependency for all users. + /// YouTube servers can reject requests and respond with `Sign in to confirm you’re not a bot` + /// See related issue: https://github.com/Hexer10/youtube_explode_dart/issues/282 + /// + /// **Will be removed soon in future releases**. + @Deprecated( + 'Can cause issues with YouTube Terms of Service and require a extra dependency for all users - Will be removed soon.\n' + 'YouTube servers can reject requests and respond with "Sign in to confirm you’re not a bot"\n' + 'See related issue https://github.com/Hexer10/youtube_explode_dart/issues/282\n', + ) customPlayerWithDownloadUrl, } diff --git a/flutter_quill_extensions/lib/src/editor/video/video_embed.dart b/flutter_quill_extensions/lib/src/editor/video/video_embed.dart index 6f3f9b8a7..f387febd6 100644 --- a/flutter_quill_extensions/lib/src/editor/video/video_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/video/video_embed.dart @@ -33,10 +33,35 @@ class QuillEditorVideoEmbedBuilder extends EmbedBuilder { assert(!kIsWeb, 'Please provide video EmbedBuilder for Web'); final videoUrl = node.value.data; - if (isYouTubeUrl(videoUrl)) { + + final customVideoBuilder = configurations.customVideoBuilder; + if (customVideoBuilder != null) { + final videoWidget = customVideoBuilder(videoUrl, readOnly); + if (videoWidget != null) { + return videoWidget; + } + } + + // ignore: deprecated_member_use_from_same_package + if (isYouTubeUrl(videoUrl) && !configurations.ignoreYouTubeSupport) { + assert(() { + debugPrint( + "It seems that you're loading a youtube video URL.\n" + 'Loading YouTube videos is no longer built-in feature as part of flutter_quill_extensions.\n' + 'This message will only appear in development mode. See https://github.com/singerdmx/flutter-quill/issues/2284\n' + 'Consider using the experimental property `QuillEditorVideoEmbedConfigurations.customVideoBuilder` in your configuration.\n' + 'This message will only included in development mode.\n', + ); + return true; + }()); + + /// Will be removed soon in future releases + + // ignore: deprecated_member_use_from_same_package return YoutubeVideoApp( videoUrl: videoUrl, readOnly: readOnly, + // ignore: deprecated_member_use_from_same_package youtubeVideoSupportMode: configurations.youtubeVideoSupportMode, ); } diff --git a/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart b/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart index f271bc22a..0b27755b2 100644 --- a/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/video/video_web_embed.dart @@ -1,8 +1,6 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:universal_html/html.dart' as html; -import 'package:youtube_player_flutter/youtube_player_flutter.dart' - show YoutubePlayer; import '../../common/utils/dart_ui/dart_ui_fake.dart' if (dart.library.js_interop) '../../common/utils/dart_ui/dart_ui_real.dart' @@ -10,6 +8,7 @@ import '../../common/utils/dart_ui/dart_ui_fake.dart' import '../../common/utils/element_utils/element_web_utils.dart'; import '../../common/utils/utils.dart'; import 'models/video_web_configurations.dart'; +import 'youtube_video_url.dart'; class QuillEditorWebVideoEmbedBuilder extends EmbedBuilder { const QuillEditorWebVideoEmbedBuilder({ @@ -34,8 +33,10 @@ class QuillEditorWebVideoEmbedBuilder extends EmbedBuilder { TextStyle textStyle, ) { var videoUrl = node.value.data; + // ignore: deprecated_member_use_from_same_package if (isYouTubeUrl(videoUrl)) { - final youtubeID = YoutubePlayer.convertUrlToId(videoUrl); + // ignore: deprecated_member_use_from_same_package + final youtubeID = convertVideoUrlToId(videoUrl); if (youtubeID != null) { videoUrl = 'https://www.youtube.com/embed/$youtubeID'; } diff --git a/flutter_quill_extensions/lib/src/editor/video/widgets/youtube_video_app.dart b/flutter_quill_extensions/lib/src/editor/video/widgets/youtube_video_app.dart index b522f0750..503aea5fd 100644 --- a/flutter_quill_extensions/lib/src/editor/video/widgets/youtube_video_app.dart +++ b/flutter_quill_extensions/lib/src/editor/video/widgets/youtube_video_app.dart @@ -3,11 +3,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' show DefaultStyles; import 'package:url_launcher/url_launcher_string.dart'; import 'package:youtube_explode_dart/youtube_explode_dart.dart'; -import 'package:youtube_player_flutter/youtube_player_flutter.dart'; import '../models/youtube_video_support_mode.dart'; +import '../youtube_video_url.dart'; import 'video_app.dart'; +/// **Will be removed soon in future releases**. +@Deprecated( + 'Will be removed in future releases. See https://github.com/singerdmx/flutter-quill/issues/2284', +) class YoutubeVideoApp extends StatefulWidget { const YoutubeVideoApp({ required this.videoUrl, @@ -24,9 +28,8 @@ class YoutubeVideoApp extends StatefulWidget { YoutubeVideoAppState createState() => YoutubeVideoAppState(); } +// ignore: deprecated_member_use_from_same_package class YoutubeVideoAppState extends State { - YoutubePlayerController? _youtubeIframeController; - /// On some platforms such as desktop, Webview is not supported yet /// as a result the youtube video player package is not supported too /// this future will be not null and fetch the video url to load it using @@ -35,7 +38,8 @@ class YoutubeVideoAppState extends State { /// Null if the video URL is not a YouTube video String? get _videoId { - return YoutubePlayer.convertUrlToId(widget.videoUrl); + // ignore: deprecated_member_use_from_same_package + return convertVideoUrlToId(widget.videoUrl); } @override @@ -46,16 +50,21 @@ class YoutubeVideoAppState extends State { return; } switch (widget.youtubeVideoSupportMode) { + // ignore: deprecated_member_use_from_same_package case YoutubeVideoSupportMode.disabled: break; + // ignore: deprecated_member_use_from_same_package case YoutubeVideoSupportMode.iframeView: - _youtubeIframeController = YoutubePlayerController( - initialVideoId: videoId, - flags: const YoutubePlayerFlags( - autoPlay: false, - ), - ); + assert(() { + debugPrint( + 'Youtube Iframe is no longer supported on non-web platforms.\n' + 'See https://github.com/singerdmx/flutter-quill/issues/2284\n' + 'This message will only included in development mode.\n', + ); + return true; + }()); break; + // ignore: deprecated_member_use_from_same_package case YoutubeVideoSupportMode.customPlayerWithDownloadUrl: _loadYoutubeVideoByDownloadUrlFuture = _loadYoutubeVideoWithVideoPlayerByVideoUrl(); @@ -85,37 +94,76 @@ class YoutubeVideoAppState extends State { @override Widget build(BuildContext context) { + assert(() { + debugPrint( + "WARNING: It seems that you're using YoutubeVideoApp widget from flutter_quill_extensions " + 'which will be removed in future releases and will cause many issues.\n' + 'Use `customVideoBuilder` in the configuration class of `QuillEditorVideoEmbedConfigurations`.\n' + 'This message is only shown in development mode.\n' + 'Refer to https://github.com/singerdmx/flutter-quill/issues/2284 if you need help.', + ); + return true; + }()); final defaultStyles = DefaultStyles.getInstance(context); switch (widget.youtubeVideoSupportMode) { + // ignore: deprecated_member_use_from_same_package case YoutubeVideoSupportMode.disabled: - throw UnsupportedError('YouTube video links are not supported'); - case YoutubeVideoSupportMode.iframeView: - final youtubeController = _youtubeIframeController; - - if (youtubeController == null) { - if (widget.readOnly) { - return _clickableVideoLinkText(defaultStyles: defaultStyles); - } - - return RichText( - text: TextSpan(text: widget.videoUrl, style: defaultStyles.link), + // Don't remove this assert, it's required to ensure + // a smoother migration for users, will be only included in development mode + assert(() { + debugPrint( + 'Loading Youtube Videos has been disabled in recent versions of flutter_quill_extensions.\n' + 'See https://github.com/singerdmx/flutter-quill/issues/2284.\n' + 'We highly suggest to use the experimental property `QuillEditorVideoEmbedConfigurations.customVideoBuilder`\n' + 'in your configuration to handle YouTube video support.\n' + 'This message will only included in development mode.\n', ); + throw UnsupportedError( + 'Loading YouTube videos is no longer supported in flutter_quill_extensions.' + 'Take a look at the debug console for more details.\n' + 'Refer to https://github.com/singerdmx/flutter-quill/issues/2284 if you need help.\n' + 'This error will only happen in development mode, in production will return a clickable video link text.\n', + ); + }()); + return _clickableVideoLinkText(defaultStyles: defaultStyles); + // ignore: deprecated_member_use_from_same_package + case YoutubeVideoSupportMode.iframeView: + if (widget.readOnly) { + return _clickableVideoLinkText(defaultStyles: defaultStyles); } - return YoutubePlayerBuilder( - player: YoutubePlayer( - controller: youtubeController, - showVideoProgressIndicator: true, - ), - builder: (context, player) { - return player; - }, + + return RichText( + text: TextSpan(text: widget.videoUrl, style: defaultStyles.link), ); + // ignore: deprecated_member_use_from_same_package case YoutubeVideoSupportMode.customPlayerWithDownloadUrl: assert( _loadYoutubeVideoByDownloadUrlFuture != null, 'The load youtube video future should not null for "${widget.youtubeVideoSupportMode}" mode', ); + assert(() { + debugPrint( + 'WARNING: Using the YouTube video download URL can violate their terms of service.\n' + 'This is already documented in customPlayerWithDownloadUrl option.\n' + 'See https://github.com/singerdmx/flutter-quill/issues/2284.\n' + 'We suggest to use the experimental property `QuillEditorVideoEmbedConfigurations.customVideoBuilder`\n' + 'in your configuration to handle YouTube video support.\n' + 'This message will only included in development mode.\n', + ); + debugPrint( + 'WARNING: Using customPlayerWithDownloadUrl might not work anymore ' + 'as YouTube servers can reject requests and respond with "Sign in to confirm you’re not a bot"\n' + 'See https://github.com/Hexer10/youtube_explode_dart/issues/282\n' + 'This message will only included in development mode.\n', + ); + throw UnsupportedError( + 'Loading YouTube videos is no longer supported in flutter_quill_extensions.' + 'Take a look at the debug console for more details.\n' + 'Refer to https://github.com/singerdmx/flutter-quill/issues/2284 if you need help.\n' + 'This error will only happen in development mode, in producation, YouTube servers will respond with "Sign in to confirm you’re not a bot".\n', + ); + }()); return FutureBuilder( future: _loadYoutubeVideoByDownloadUrlFuture, @@ -134,10 +182,4 @@ class YoutubeVideoAppState extends State { ); } } - - @override - void dispose() { - _youtubeIframeController?.dispose(); - super.dispose(); - } } diff --git a/flutter_quill_extensions/lib/src/editor/video/youtube_video_url.dart b/flutter_quill_extensions/lib/src/editor/video/youtube_video_url.dart new file mode 100644 index 000000000..379f9fdb0 --- /dev/null +++ b/flutter_quill_extensions/lib/src/editor/video/youtube_video_url.dart @@ -0,0 +1,32 @@ +import 'package:meta/meta.dart'; + +/// Function copied from https://github.com/sarbagyastha/youtube_player_flutter/blob/f8e1e79991066bcc70f0a7c93941ca0d54b7370e/packages/youtube_player_flutter/lib/src/player/youtube_player.dart#L154 +/// and is not written as part of this project. +/// +/// Used as quick response for https://github.com/singerdmx/flutter-quill/issues/2284 +@experimental +@internal +@Deprecated( + 'Will be removed in future releases, for now included as quick response to https://github.com/singerdmx/flutter-quill/issues/2284', +) +String? convertVideoUrlToId(String url, {bool trimWhitespaces = true}) { + if (!url.contains('http') && (url.length == 11)) return url; + if (trimWhitespaces) url = url.trim(); + + for (final exp in [ + RegExp( + r'^https:\/\/(?:www\.|m\.)?youtube\.com\/watch\?v=([_\-a-zA-Z0-9]{11}).*$'), + RegExp( + r'^https:\/\/(?:music\.)?youtube\.com\/watch\?v=([_\-a-zA-Z0-9]{11}).*$'), + RegExp( + r'^https:\/\/(?:www\.|m\.)?youtube\.com\/shorts\/([_\-a-zA-Z0-9]{11}).*$'), + RegExp( + r'^https:\/\/(?:www\.|m\.)?youtube(?:-nocookie)?\.com\/embed\/([_\-a-zA-Z0-9]{11}).*$'), + RegExp(r'^https:\/\/youtu\.be\/([_\-a-zA-Z0-9]{11}).*$') + ]) { + final Match? match = exp.firstMatch(url); + if (match != null && match.groupCount >= 1) return match.group(1); + } + + return null; +} diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 3763f76fd..277f6dbf2 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -37,11 +37,11 @@ dependencies: flutter_quill: ^10.7.2 photo_view: ^0.15.0 + # TODO: Remove youtube_explode_dart youtube_explode_dart: ^2.2.1 # Plugins video_player: ^2.8.1 - youtube_player_flutter: ^9.0.1 url_launcher: ^6.2.1 super_clipboard: ^0.8.22 gal: ^2.3.0 From b8e6af1ee3dc322e4150d137c4a927d3e9a97871 Mon Sep 17 00:00:00 2001 From: EchoEllet Date: Wed, 25 Sep 2024 17:18:41 +0000 Subject: [PATCH 063/113] chore(version): update to version 10.8.0 --- CHANGELOG.md | 110 ++++++++++++++++++ CHANGELOG_DATA.json | 1 + dart_quill_delta/CHANGELOG.md | 110 ++++++++++++++++++ dart_quill_delta/pubspec.yaml | 2 +- .../Flutter/GeneratedPluginRegistrant.swift | 2 - .../flutter/generated_plugin_registrant.cc | 3 - .../windows/flutter/generated_plugins.cmake | 1 - flutter_quill_extensions/CHANGELOG.md | 110 ++++++++++++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 110 ++++++++++++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 12 files changed, 445 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7a579c5e..ff9e817c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,116 @@ All notable changes to this project will be documented in this file. +## 10.8.0 + +> [!CAUTION] +> This release can be breaking change for `flutter_quill_extensions` users as it remove the built-in support for loading YouTube videos + +If you're using [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) then this release, can be a breaking change for you if you load videos in the editor and expect YouTube videos to be supported, [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) and [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) are no longer dependencies of the extensions package, which are used to support loading YouTube Iframe videos on non-web platforms, more details about the discussion and reasons in [#2286](https://github.com/singerdmx/flutter-quill/pull/2286) and [#2284](https://github.com/singerdmx/flutter-quill/issues/2284). + +We have added an experimental property that gives you more flexibility and control about the implementation you want to use for loading videos. + +> [!WARNING] +> It's likely to experience some common issues while implementing this feature, especially on desktop platforms as the support for [flutter_inappwebview_windows](https://pub.dev/packages/flutter_inappwebview_windows) and [flutter_inappwebview_macos](https://pub.dev/packages/flutter_inappwebview_macos) before 2 days. Some of the issues are in the Flutter Quill editor. + +If you want loading YouTube videos to be a feature again with the latest version of Flutter Quill, you can use an existing plugin or package, or implement your own solution. For example, you might use [`youtube_video_player`](https://pub.dev/packages/youtube_video_player) or [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter), which was previously used in [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions). + +Here’s an example setup using `youtube_player_flutter`: + +```shell +flutter pub add youtube_player_flutter +``` + +Example widget configuration: + +```dart +import 'package:flutter/material.dart'; +import 'package:youtube_player_flutter/youtube_player_flutter.dart'; + +class YoutubeVideoPlayer extends StatefulWidget { + const YoutubeVideoPlayer({required this.videoUrl, super.key}); + + final String videoUrl; + + @override + State createState() => _YoutubeVideoPlayerState(); +} + +class _YoutubeVideoPlayerState extends State { + late final YoutubePlayerController _youtubePlayerController; + @override + void initState() { + super.initState(); + _youtubePlayerController = YoutubePlayerController( + initialVideoId: YoutubePlayer.convertUrlToId(widget.videoUrl) ?? + (throw StateError('Expect a valid video URL')), + flags: const YoutubePlayerFlags( + autoPlay: true, + mute: true, + ), + ); + } + + @override + Widget build(BuildContext context) { + return YoutubePlayer( + controller: _youtubePlayerController, + showVideoProgressIndicator: true, + ); + } + + @override + void dispose() { + _youtubePlayerController.dispose(); + super.dispose(); + } +} + +``` + +Then, integrate it with `QuillEditorVideoEmbedConfigurations` + +```dart +FlutterQuillEmbeds.editorBuilders( + videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations( + customVideoBuilder: (videoUrl, readOnly) { + // Example: Check for YouTube Video URL and return your + // YouTube video widget here. + bool isYouTubeUrl(String videoUrl) { + try { + final uri = Uri.parse(videoUrl); + return uri.host == 'www.youtube.com' || + uri.host == 'youtube.com' || + uri.host == 'youtu.be' || + uri.host == 'www.youtu.be'; + } catch (_) { + return false; + } + } + + if (isYouTubeUrl(videoUrl)) { + return YoutubeVideoPlayer( + videoUrl: videoUrl, + ); + } + + // Return null to fallback to the default logic + return null; + }, + ignoreYouTubeSupport: true, + ), +); +``` + +> [!NOTE] +> This example illustrates a basic approach, additional adjustments might be necessary to meet your specific needs. YouTube video support is no longer included in this project. Keep in mind that `customVideoBuilder` is experimental and can change without being considered as breaking change. More details in [breaking changes](https://github.com/singerdmx/flutter-quill#-breaking-changes) section. + +[`super_clipboard`](https://pub.dev/packages/super_clipboard) will also no longer a dependency of `flutter_quill_extensions` once [PR #2230](https://github.com/singerdmx/flutter-quill/pull/2230) is ready. + +We're looking forward to your feedback. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.7...v10.8.0 + ## 10.7.7 This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230) diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index b5afddc49..335a2872b 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.8.0": "> [!CAUTION]\r\n> This release can be breaking change for `flutter_quill_extensions` users as it remove the built-in support for loading YouTube videos\r\n\r\nIf you're using [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) then this release, can be a breaking change for you if you load videos in the editor and expect YouTube videos to be supported, [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) and [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) are no longer dependencies of the extensions package, which are used to support loading YouTube Iframe videos on non-web platforms, more details about the discussion and reasons in [#2286](https://github.com/singerdmx/flutter-quill/pull/2286) and [#2284](https://github.com/singerdmx/flutter-quill/issues/2284).\r\n\r\nWe have added an experimental property that gives you more flexibility and control about the implementation you want to use for loading videos.\r\n\r\n> [!WARNING]\r\n> It's likely to experience some common issues while implementing this feature, especially on desktop platforms as the support for [flutter_inappwebview_windows](https://pub.dev/packages/flutter_inappwebview_windows) and [flutter_inappwebview_macos](https://pub.dev/packages/flutter_inappwebview_macos) before 2 days. Some of the issues are in the Flutter Quill editor.\r\n\r\nIf you want loading YouTube videos to be a feature again with the latest version of Flutter Quill, you can use an existing plugin or package, or implement your own solution. For example, you might use [`youtube_video_player`](https://pub.dev/packages/youtube_video_player) or [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter), which was previously used in [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions).\r\n\r\nHere’s an example setup using `youtube_player_flutter`:\r\n\r\n```shell\r\nflutter pub add youtube_player_flutter\r\n```\r\n\r\nExample widget configuration:\r\n\r\n```dart\r\nimport 'package:flutter/material.dart';\r\nimport 'package:youtube_player_flutter/youtube_player_flutter.dart';\r\n\r\nclass YoutubeVideoPlayer extends StatefulWidget {\r\n const YoutubeVideoPlayer({required this.videoUrl, super.key});\r\n\r\n final String videoUrl;\r\n\r\n @override\r\n State createState() => _YoutubeVideoPlayerState();\r\n}\r\n\r\nclass _YoutubeVideoPlayerState extends State {\r\n late final YoutubePlayerController _youtubePlayerController;\r\n @override\r\n void initState() {\r\n super.initState();\r\n _youtubePlayerController = YoutubePlayerController(\r\n initialVideoId: YoutubePlayer.convertUrlToId(widget.videoUrl) ??\r\n (throw StateError('Expect a valid video URL')),\r\n flags: const YoutubePlayerFlags(\r\n autoPlay: true,\r\n mute: true,\r\n ),\r\n );\r\n }\r\n\r\n @override\r\n Widget build(BuildContext context) {\r\n return YoutubePlayer(\r\n controller: _youtubePlayerController,\r\n showVideoProgressIndicator: true,\r\n );\r\n }\r\n\r\n @override\r\n void dispose() {\r\n _youtubePlayerController.dispose();\r\n super.dispose();\r\n }\r\n}\r\n\r\n```\r\n\r\nThen, integrate it with `QuillEditorVideoEmbedConfigurations`\r\n\r\n```dart\r\nFlutterQuillEmbeds.editorBuilders(\r\n videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations(\r\n customVideoBuilder: (videoUrl, readOnly) {\r\n // Example: Check for YouTube Video URL and return your\r\n // YouTube video widget here.\r\n bool isYouTubeUrl(String videoUrl) {\r\n try {\r\n final uri = Uri.parse(videoUrl);\r\n return uri.host == 'www.youtube.com' ||\r\n uri.host == 'youtube.com' ||\r\n uri.host == 'youtu.be' ||\r\n uri.host == 'www.youtu.be';\r\n } catch (_) {\r\n return false;\r\n }\r\n }\r\n\r\n if (isYouTubeUrl(videoUrl)) {\r\n return YoutubeVideoPlayer(\r\n videoUrl: videoUrl,\r\n );\r\n }\r\n\r\n // Return null to fallback to the default logic\r\n return null;\r\n },\r\n ignoreYouTubeSupport: true,\r\n ),\r\n);\r\n```\r\n\r\n> [!NOTE]\r\n> This example illustrates a basic approach, additional adjustments might be necessary to meet your specific needs. YouTube video support is no longer included in this project. Keep in mind that `customVideoBuilder` is experimental and can change without being considered as breaking change. More details in [breaking changes](https://github.com/singerdmx/flutter-quill#-breaking-changes) section.\r\n\r\n[`super_clipboard`](https://pub.dev/packages/super_clipboard) will also no longer a dependency of `flutter_quill_extensions` once [PR #2230](https://github.com/singerdmx/flutter-quill/pull/2230) is ready.\r\n\r\nWe're looking forward to your feedback.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.7...v10.8.0", "10.7.7": "This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230)\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.6...v10.7.7", "10.7.6": "* Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267\r\n* docs: add important note for contributors before introducing new features by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2269\r\n* docs(readme): add 'Breaking Changes' section by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2275\r\n* Fix: Resolved issue with broken IME composing rect in Windows desktop(re-implementation) by @agata in https://github.com/singerdmx/flutter-quill/pull/2282\r\n\r\n## New Contributors\r\n* @Luismi74 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2267\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.5...v10.7.6", "10.7.5": "* fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265\r\n* revert: \"Resolved issue with broken IME composing rect in Windows desktop\" by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2266\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.4...v10.7.5", diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index c7a579c5e..ff9e817c8 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -4,6 +4,116 @@ All notable changes to this project will be documented in this file. +## 10.8.0 + +> [!CAUTION] +> This release can be breaking change for `flutter_quill_extensions` users as it remove the built-in support for loading YouTube videos + +If you're using [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) then this release, can be a breaking change for you if you load videos in the editor and expect YouTube videos to be supported, [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) and [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) are no longer dependencies of the extensions package, which are used to support loading YouTube Iframe videos on non-web platforms, more details about the discussion and reasons in [#2286](https://github.com/singerdmx/flutter-quill/pull/2286) and [#2284](https://github.com/singerdmx/flutter-quill/issues/2284). + +We have added an experimental property that gives you more flexibility and control about the implementation you want to use for loading videos. + +> [!WARNING] +> It's likely to experience some common issues while implementing this feature, especially on desktop platforms as the support for [flutter_inappwebview_windows](https://pub.dev/packages/flutter_inappwebview_windows) and [flutter_inappwebview_macos](https://pub.dev/packages/flutter_inappwebview_macos) before 2 days. Some of the issues are in the Flutter Quill editor. + +If you want loading YouTube videos to be a feature again with the latest version of Flutter Quill, you can use an existing plugin or package, or implement your own solution. For example, you might use [`youtube_video_player`](https://pub.dev/packages/youtube_video_player) or [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter), which was previously used in [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions). + +Here’s an example setup using `youtube_player_flutter`: + +```shell +flutter pub add youtube_player_flutter +``` + +Example widget configuration: + +```dart +import 'package:flutter/material.dart'; +import 'package:youtube_player_flutter/youtube_player_flutter.dart'; + +class YoutubeVideoPlayer extends StatefulWidget { + const YoutubeVideoPlayer({required this.videoUrl, super.key}); + + final String videoUrl; + + @override + State createState() => _YoutubeVideoPlayerState(); +} + +class _YoutubeVideoPlayerState extends State { + late final YoutubePlayerController _youtubePlayerController; + @override + void initState() { + super.initState(); + _youtubePlayerController = YoutubePlayerController( + initialVideoId: YoutubePlayer.convertUrlToId(widget.videoUrl) ?? + (throw StateError('Expect a valid video URL')), + flags: const YoutubePlayerFlags( + autoPlay: true, + mute: true, + ), + ); + } + + @override + Widget build(BuildContext context) { + return YoutubePlayer( + controller: _youtubePlayerController, + showVideoProgressIndicator: true, + ); + } + + @override + void dispose() { + _youtubePlayerController.dispose(); + super.dispose(); + } +} + +``` + +Then, integrate it with `QuillEditorVideoEmbedConfigurations` + +```dart +FlutterQuillEmbeds.editorBuilders( + videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations( + customVideoBuilder: (videoUrl, readOnly) { + // Example: Check for YouTube Video URL and return your + // YouTube video widget here. + bool isYouTubeUrl(String videoUrl) { + try { + final uri = Uri.parse(videoUrl); + return uri.host == 'www.youtube.com' || + uri.host == 'youtube.com' || + uri.host == 'youtu.be' || + uri.host == 'www.youtu.be'; + } catch (_) { + return false; + } + } + + if (isYouTubeUrl(videoUrl)) { + return YoutubeVideoPlayer( + videoUrl: videoUrl, + ); + } + + // Return null to fallback to the default logic + return null; + }, + ignoreYouTubeSupport: true, + ), +); +``` + +> [!NOTE] +> This example illustrates a basic approach, additional adjustments might be necessary to meet your specific needs. YouTube video support is no longer included in this project. Keep in mind that `customVideoBuilder` is experimental and can change without being considered as breaking change. More details in [breaking changes](https://github.com/singerdmx/flutter-quill#-breaking-changes) section. + +[`super_clipboard`](https://pub.dev/packages/super_clipboard) will also no longer a dependency of `flutter_quill_extensions` once [PR #2230](https://github.com/singerdmx/flutter-quill/pull/2230) is ready. + +We're looking forward to your feedback. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.7...v10.8.0 + ## 10.7.7 This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230) diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index de594c1df..8d4072bfa 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 10.7.7 +version: 10.8.0 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index eabf85a3e..bf1bbe800 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,7 +8,6 @@ import Foundation import desktop_drop import device_info_plus import file_selector_macos -import flutter_inappwebview_macos import gal import irondash_engine_context import path_provider_foundation @@ -22,7 +21,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) - InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin")) GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin")) IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc index 8e3614f6f..084810413 100644 --- a/example/windows/flutter/generated_plugin_registrant.cc +++ b/example/windows/flutter/generated_plugin_registrant.cc @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -20,8 +19,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("DesktopDropPlugin")); FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); - FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi")); GalPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("GalPluginCApi")); IrondashEngineContextPluginCApiRegisterWithRegistrar( diff --git a/example/windows/flutter/generated_plugins.cmake b/example/windows/flutter/generated_plugins.cmake index a10959609..f568d1445 100644 --- a/example/windows/flutter/generated_plugins.cmake +++ b/example/windows/flutter/generated_plugins.cmake @@ -5,7 +5,6 @@ list(APPEND FLUTTER_PLUGIN_LIST desktop_drop file_selector_windows - flutter_inappwebview_windows gal irondash_engine_context share_plus diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index c7a579c5e..ff9e817c8 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,116 @@ All notable changes to this project will be documented in this file. +## 10.8.0 + +> [!CAUTION] +> This release can be breaking change for `flutter_quill_extensions` users as it remove the built-in support for loading YouTube videos + +If you're using [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) then this release, can be a breaking change for you if you load videos in the editor and expect YouTube videos to be supported, [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) and [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) are no longer dependencies of the extensions package, which are used to support loading YouTube Iframe videos on non-web platforms, more details about the discussion and reasons in [#2286](https://github.com/singerdmx/flutter-quill/pull/2286) and [#2284](https://github.com/singerdmx/flutter-quill/issues/2284). + +We have added an experimental property that gives you more flexibility and control about the implementation you want to use for loading videos. + +> [!WARNING] +> It's likely to experience some common issues while implementing this feature, especially on desktop platforms as the support for [flutter_inappwebview_windows](https://pub.dev/packages/flutter_inappwebview_windows) and [flutter_inappwebview_macos](https://pub.dev/packages/flutter_inappwebview_macos) before 2 days. Some of the issues are in the Flutter Quill editor. + +If you want loading YouTube videos to be a feature again with the latest version of Flutter Quill, you can use an existing plugin or package, or implement your own solution. For example, you might use [`youtube_video_player`](https://pub.dev/packages/youtube_video_player) or [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter), which was previously used in [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions). + +Here’s an example setup using `youtube_player_flutter`: + +```shell +flutter pub add youtube_player_flutter +``` + +Example widget configuration: + +```dart +import 'package:flutter/material.dart'; +import 'package:youtube_player_flutter/youtube_player_flutter.dart'; + +class YoutubeVideoPlayer extends StatefulWidget { + const YoutubeVideoPlayer({required this.videoUrl, super.key}); + + final String videoUrl; + + @override + State createState() => _YoutubeVideoPlayerState(); +} + +class _YoutubeVideoPlayerState extends State { + late final YoutubePlayerController _youtubePlayerController; + @override + void initState() { + super.initState(); + _youtubePlayerController = YoutubePlayerController( + initialVideoId: YoutubePlayer.convertUrlToId(widget.videoUrl) ?? + (throw StateError('Expect a valid video URL')), + flags: const YoutubePlayerFlags( + autoPlay: true, + mute: true, + ), + ); + } + + @override + Widget build(BuildContext context) { + return YoutubePlayer( + controller: _youtubePlayerController, + showVideoProgressIndicator: true, + ); + } + + @override + void dispose() { + _youtubePlayerController.dispose(); + super.dispose(); + } +} + +``` + +Then, integrate it with `QuillEditorVideoEmbedConfigurations` + +```dart +FlutterQuillEmbeds.editorBuilders( + videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations( + customVideoBuilder: (videoUrl, readOnly) { + // Example: Check for YouTube Video URL and return your + // YouTube video widget here. + bool isYouTubeUrl(String videoUrl) { + try { + final uri = Uri.parse(videoUrl); + return uri.host == 'www.youtube.com' || + uri.host == 'youtube.com' || + uri.host == 'youtu.be' || + uri.host == 'www.youtu.be'; + } catch (_) { + return false; + } + } + + if (isYouTubeUrl(videoUrl)) { + return YoutubeVideoPlayer( + videoUrl: videoUrl, + ); + } + + // Return null to fallback to the default logic + return null; + }, + ignoreYouTubeSupport: true, + ), +); +``` + +> [!NOTE] +> This example illustrates a basic approach, additional adjustments might be necessary to meet your specific needs. YouTube video support is no longer included in this project. Keep in mind that `customVideoBuilder` is experimental and can change without being considered as breaking change. More details in [breaking changes](https://github.com/singerdmx/flutter-quill#-breaking-changes) section. + +[`super_clipboard`](https://pub.dev/packages/super_clipboard) will also no longer a dependency of `flutter_quill_extensions` once [PR #2230](https://github.com/singerdmx/flutter-quill/pull/2230) is ready. + +We're looking forward to your feedback. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.7...v10.8.0 + ## 10.7.7 This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 277f6dbf2..c502a0112 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.7.7 +version: 10.8.0 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index c7a579c5e..ff9e817c8 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,116 @@ All notable changes to this project will be documented in this file. +## 10.8.0 + +> [!CAUTION] +> This release can be breaking change for `flutter_quill_extensions` users as it remove the built-in support for loading YouTube videos + +If you're using [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) then this release, can be a breaking change for you if you load videos in the editor and expect YouTube videos to be supported, [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) and [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) are no longer dependencies of the extensions package, which are used to support loading YouTube Iframe videos on non-web platforms, more details about the discussion and reasons in [#2286](https://github.com/singerdmx/flutter-quill/pull/2286) and [#2284](https://github.com/singerdmx/flutter-quill/issues/2284). + +We have added an experimental property that gives you more flexibility and control about the implementation you want to use for loading videos. + +> [!WARNING] +> It's likely to experience some common issues while implementing this feature, especially on desktop platforms as the support for [flutter_inappwebview_windows](https://pub.dev/packages/flutter_inappwebview_windows) and [flutter_inappwebview_macos](https://pub.dev/packages/flutter_inappwebview_macos) before 2 days. Some of the issues are in the Flutter Quill editor. + +If you want loading YouTube videos to be a feature again with the latest version of Flutter Quill, you can use an existing plugin or package, or implement your own solution. For example, you might use [`youtube_video_player`](https://pub.dev/packages/youtube_video_player) or [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter), which was previously used in [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions). + +Here’s an example setup using `youtube_player_flutter`: + +```shell +flutter pub add youtube_player_flutter +``` + +Example widget configuration: + +```dart +import 'package:flutter/material.dart'; +import 'package:youtube_player_flutter/youtube_player_flutter.dart'; + +class YoutubeVideoPlayer extends StatefulWidget { + const YoutubeVideoPlayer({required this.videoUrl, super.key}); + + final String videoUrl; + + @override + State createState() => _YoutubeVideoPlayerState(); +} + +class _YoutubeVideoPlayerState extends State { + late final YoutubePlayerController _youtubePlayerController; + @override + void initState() { + super.initState(); + _youtubePlayerController = YoutubePlayerController( + initialVideoId: YoutubePlayer.convertUrlToId(widget.videoUrl) ?? + (throw StateError('Expect a valid video URL')), + flags: const YoutubePlayerFlags( + autoPlay: true, + mute: true, + ), + ); + } + + @override + Widget build(BuildContext context) { + return YoutubePlayer( + controller: _youtubePlayerController, + showVideoProgressIndicator: true, + ); + } + + @override + void dispose() { + _youtubePlayerController.dispose(); + super.dispose(); + } +} + +``` + +Then, integrate it with `QuillEditorVideoEmbedConfigurations` + +```dart +FlutterQuillEmbeds.editorBuilders( + videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations( + customVideoBuilder: (videoUrl, readOnly) { + // Example: Check for YouTube Video URL and return your + // YouTube video widget here. + bool isYouTubeUrl(String videoUrl) { + try { + final uri = Uri.parse(videoUrl); + return uri.host == 'www.youtube.com' || + uri.host == 'youtube.com' || + uri.host == 'youtu.be' || + uri.host == 'www.youtu.be'; + } catch (_) { + return false; + } + } + + if (isYouTubeUrl(videoUrl)) { + return YoutubeVideoPlayer( + videoUrl: videoUrl, + ); + } + + // Return null to fallback to the default logic + return null; + }, + ignoreYouTubeSupport: true, + ), +); +``` + +> [!NOTE] +> This example illustrates a basic approach, additional adjustments might be necessary to meet your specific needs. YouTube video support is no longer included in this project. Keep in mind that `customVideoBuilder` is experimental and can change without being considered as breaking change. More details in [breaking changes](https://github.com/singerdmx/flutter-quill#-breaking-changes) section. + +[`super_clipboard`](https://pub.dev/packages/super_clipboard) will also no longer a dependency of `flutter_quill_extensions` once [PR #2230](https://github.com/singerdmx/flutter-quill/pull/2230) is ready. + +We're looking forward to your feedback. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.7...v10.8.0 + ## 10.7.7 This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230) diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 2661a3b76..8247d0455 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.7.7 +version: 10.8.0 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 9cc2b0626..3c3b941b9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.7.7 +version: 10.8.0 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From e34ae5f6c547295829d8b96fd0b8f79900c664e6 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 25 Sep 2024 23:01:46 +0300 Subject: [PATCH 064/113] chore(example): exclude flutter_inappwebview_web web support js file from index.html --- example/web/index.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/example/web/index.html b/example/web/index.html index e627ce09a..27dfe197d 100644 --- a/example/web/index.html +++ b/example/web/index.html @@ -36,9 +36,6 @@ - - - From ffe66fb8a177f2b6a764fdaa40487798a9065be8 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 27 Sep 2024 17:58:34 +0300 Subject: [PATCH 065/113] chore(deps): update dev dependency flutter_lints to 5.0.0, solve warnings (#2292) * chore(deps): update dev dependency flutter_lints to 5.0.0, solve warnings * chore: remove redundant analysis error ignore * chore: add avoid_web_libraries_in_flutter rule, remove empty analyzer declaration --- analysis_options.yaml | 5 +---- dart_quill_delta/pubspec.yaml | 1 + example/pubspec.yaml | 2 +- flutter_quill_extensions/analysis_options.yaml | 5 +---- flutter_quill_extensions/lib/flutter_quill_extensions.dart | 2 +- flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/analysis_options.yaml | 5 +---- flutter_quill_test/lib/flutter_quill_test.dart | 2 +- flutter_quill_test/pubspec.yaml | 2 +- lib/extensions.dart | 2 +- lib/flutter_quill.dart | 2 +- lib/quill_delta.dart | 2 +- lib/translations.dart | 2 +- pubspec.yaml | 2 +- quill_native_bridge/analysis_options.yaml | 2 +- quill_native_bridge/pubspec.yaml | 2 +- 16 files changed, 16 insertions(+), 24 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 91ce64695..b6065426f 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,9 +1,5 @@ include: package:flutter_lints/flutter.yaml -analyzer: - errors: - undefined_prefixed_name: ignore - unsafe_html: ignore linter: rules: always_declare_return_types: true @@ -33,3 +29,4 @@ linter: unnecessary_lambdas: true unnecessary_parenthesis: true unnecessary_string_interpolations: true + avoid_web_libraries_in_flutter: true diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index 8d4072bfa..f52527a58 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -15,5 +15,6 @@ dependencies: quiver: ^3.2.1 dev_dependencies: + # TODO: Using 4.0.0 to not require higher version of Dart SDK lints: ^4.0.0 test: ^1.24.0 diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 5c0c784fd..b5844399c 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -66,7 +66,7 @@ dependency_overrides: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^4.0.0 + flutter_lints: ^5.0.0 build_runner: ^2.4.8 flutter_gen_runner: ^5.4.0 diff --git a/flutter_quill_extensions/analysis_options.yaml b/flutter_quill_extensions/analysis_options.yaml index f1a381720..42a46376c 100644 --- a/flutter_quill_extensions/analysis_options.yaml +++ b/flutter_quill_extensions/analysis_options.yaml @@ -1,9 +1,5 @@ include: package:flutter_lints/flutter.yaml -analyzer: - errors: - undefined_prefixed_name: ignore - unsafe_html: ignore linter: rules: always_declare_return_types: true @@ -34,3 +30,4 @@ linter: unnecessary_lambdas: true unnecessary_parenthesis: true unnecessary_string_interpolations: true + avoid_web_libraries_in_flutter: true diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 7a9bec821..3abf9314e 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -1,4 +1,4 @@ -library flutter_quill_extensions; +library; // ignore: implementation_imports import 'package:flutter_quill/src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index c502a0112..38d6a241d 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -51,7 +51,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^4.0.0 + flutter_lints: ^5.0.0 flutter: uses-material-design: true diff --git a/flutter_quill_test/analysis_options.yaml b/flutter_quill_test/analysis_options.yaml index f1a381720..42a46376c 100644 --- a/flutter_quill_test/analysis_options.yaml +++ b/flutter_quill_test/analysis_options.yaml @@ -1,9 +1,5 @@ include: package:flutter_lints/flutter.yaml -analyzer: - errors: - undefined_prefixed_name: ignore - unsafe_html: ignore linter: rules: always_declare_return_types: true @@ -34,3 +30,4 @@ linter: unnecessary_lambdas: true unnecessary_parenthesis: true unnecessary_string_interpolations: true + avoid_web_libraries_in_flutter: true diff --git a/flutter_quill_test/lib/flutter_quill_test.dart b/flutter_quill_test/lib/flutter_quill_test.dart index 988e4e823..310ec2d05 100644 --- a/flutter_quill_test/lib/flutter_quill_test.dart +++ b/flutter_quill_test/lib/flutter_quill_test.dart @@ -1,3 +1,3 @@ -library flutter_quill_test; +library; export 'src/test/widget_tester_extension.dart'; diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 8247d0455..9fe894518 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -33,7 +33,7 @@ dependencies: sdk: flutter dev_dependencies: - flutter_lints: ^4.0.0 + flutter_lints: ^5.0.0 flutter: uses-material-design: true diff --git a/lib/extensions.dart b/lib/extensions.dart index 96226bc9f..9ce60ebf1 100644 --- a/lib/extensions.dart +++ b/lib/extensions.dart @@ -3,7 +3,7 @@ 'to expose certain internal APIs and should not be used directly, as it is subject to breaking changes.\n' 'The replacement is flutter_quill_internal.dart which is also for internal use only.', ) -library flutter_quill.extensions; +library; // This file contains exports that are meant to be used // internally and are not part of the public API as diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index d2adcfc4b..e54b8ff00 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -1,4 +1,4 @@ -library flutter_quill; +library; export 'src/common/structs/horizontal_spacing.dart'; export 'src/common/structs/image_url.dart'; diff --git a/lib/quill_delta.dart b/lib/quill_delta.dart index dc3a0a01c..6418b755a 100644 --- a/lib/quill_delta.dart +++ b/lib/quill_delta.dart @@ -1,3 +1,3 @@ -library flutter_quill.delta; +library; export 'package:dart_quill_delta/dart_quill_delta.dart'; diff --git a/lib/translations.dart b/lib/translations.dart index 2906e16c1..fe3f03591 100644 --- a/lib/translations.dart +++ b/lib/translations.dart @@ -1,4 +1,4 @@ -library flutter_quill.translations; +library; export 'src/l10n/extensions/localizations_ext.dart'; export 'src/l10n/widgets/localizations.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 3c3b941b9..92bde70ac 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,7 +65,7 @@ dependencies: quill_native_bridge: '>=10.5.14 <=10.6.2' dev_dependencies: - flutter_lints: ^4.0.0 + flutter_lints: ^5.0.0 flutter_test: sdk: flutter flutter_quill_test: ^10.0.0 diff --git a/quill_native_bridge/analysis_options.yaml b/quill_native_bridge/analysis_options.yaml index f9d394db2..b6065426f 100644 --- a/quill_native_bridge/analysis_options.yaml +++ b/quill_native_bridge/analysis_options.yaml @@ -1,6 +1,5 @@ include: package:flutter_lints/flutter.yaml -analyzer: linter: rules: always_declare_return_types: true @@ -30,3 +29,4 @@ linter: unnecessary_lambdas: true unnecessary_parenthesis: true unnecessary_string_interpolations: true + avoid_web_libraries_in_flutter: true diff --git a/quill_native_bridge/pubspec.yaml b/quill_native_bridge/pubspec.yaml index 58228fcd9..da87139e3 100644 --- a/quill_native_bridge/pubspec.yaml +++ b/quill_native_bridge/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^4.0.0 + flutter_lints: ^5.0.0 flutter: plugin: From 60ff374c53973dad1134a934cea4a9270a8bc5a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9ts=20Gerg=C5=91?= Date: Fri, 27 Sep 2024 17:02:39 +0200 Subject: [PATCH 066/113] Add Hungarian (hu) localization (#2291) * Create quill_hu.arb * Generate 'hu' dart files --- .../l10n/generated/quill_localizations.dart | 5 + .../generated/quill_localizations_hu.dart | 309 ++++++++++++++++++ lib/src/l10n/quill_hu.arb | 112 +++++++ 3 files changed, 426 insertions(+) create mode 100644 lib/src/l10n/generated/quill_localizations_hu.dart create mode 100644 lib/src/l10n/quill_hu.arb diff --git a/lib/src/l10n/generated/quill_localizations.dart b/lib/src/l10n/generated/quill_localizations.dart index c90860536..d82f7d67c 100644 --- a/lib/src/l10n/generated/quill_localizations.dart +++ b/lib/src/l10n/generated/quill_localizations.dart @@ -19,6 +19,7 @@ import 'quill_localizations_fa.dart'; import 'quill_localizations_fr.dart'; import 'quill_localizations_he.dart'; import 'quill_localizations_hi.dart'; +import 'quill_localizations_hu.dart'; import 'quill_localizations_id.dart'; import 'quill_localizations_it.dart'; import 'quill_localizations_ja.dart'; @@ -146,6 +147,7 @@ abstract class FlutterQuillLocalizations { Locale('fr'), Locale('he'), Locale('hi'), + Locale('hu'), Locale('id'), Locale('it'), Locale('ja'), @@ -786,6 +788,7 @@ class _FlutterQuillLocalizationsDelegate 'fr', 'he', 'hi', + 'hu', 'id', 'it', 'ja', @@ -893,6 +896,8 @@ FlutterQuillLocalizations lookupFlutterQuillLocalizations(Locale locale) { return FlutterQuillLocalizationsHe(); case 'hi': return FlutterQuillLocalizationsHi(); + case 'hu': + return FlutterQuillLocalizationsHu(); case 'id': return FlutterQuillLocalizationsId(); case 'it': diff --git a/lib/src/l10n/generated/quill_localizations_hu.dart b/lib/src/l10n/generated/quill_localizations_hu.dart new file mode 100644 index 000000000..17365b96d --- /dev/null +++ b/lib/src/l10n/generated/quill_localizations_hu.dart @@ -0,0 +1,309 @@ +import 'quill_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for Hungarian (`hu`). +class FlutterQuillLocalizationsHu extends FlutterQuillLocalizations { + FlutterQuillLocalizationsHu([String locale = 'hu']) : super(locale); + + @override + String get pasteLink => 'Link beillesztése'; + + @override + String get ok => 'Ok'; + + @override + String get selectColor => 'Szín kiválasztása'; + + @override + String get gallery => 'Galéria'; + + @override + String get link => 'Link'; + + @override + String get open => 'Megnyitás'; + + @override + String get copy => 'Másolás'; + + @override + String get remove => 'Eltávolítás'; + + @override + String get save => 'Mentés'; + + @override + String get zoom => 'Nagyítás'; + + @override + String get saved => 'Mentve'; + + @override + String get text => 'Szöveg'; + + @override + String get resize => 'Átméretezés'; + + @override + String get width => 'Szélesség'; + + @override + String get height => 'Magasság'; + + @override + String get size => 'Méret'; + + @override + String get small => 'Kicsi'; + + @override + String get large => 'Nagy'; + + @override + String get huge => 'Óriási'; + + @override + String get clear => 'Törlés'; + + @override + String get font => 'Betűtípus'; + + @override + String get search => 'Keresés'; + + @override + String get camera => 'Kamera'; + + @override + String get video => 'Videó'; + + @override + String get undo => 'Visszavonás'; + + @override + String get redo => 'Újra'; + + @override + String get fontFamily => 'Betűtípus'; + + @override + String get fontSize => 'Betűméret'; + + @override + String get bold => 'Félkövér'; + + @override + String get subscript => 'Alsó index'; + + @override + String get superscript => 'Felső index'; + + @override + String get italic => 'Dőlt'; + + @override + String get underline => 'Aláhúzás'; + + @override + String get strikeThrough => 'Áthúzás'; + + @override + String get inlineCode => 'Kód'; + + @override + String get fontColor => 'Betűszín'; + + @override + String get backgroundColor => 'Háttérszín'; + + @override + String get clearFormat => 'Formátum törlése'; + + @override + String get alignLeft => 'Balra igazítás'; + + @override + String get alignCenter => 'Középre igazítás'; + + @override + String get alignRight => 'Jobbra igazítás'; + + @override + String get alignJustify => 'Sorkizárt'; + + @override + String get justifyWinWidth => 'Sorkizárt ablak szélesség'; + + @override + String get textDirection => 'Szöveg irány'; + + @override + String get headerStyle => 'Fejléc stílus'; + + @override + String get normal => 'Normál'; + + @override + String get heading1 => 'Fejléc 1'; + + @override + String get heading2 => 'Fejléc 2'; + + @override + String get heading3 => 'Fejléc 3'; + + @override + String get heading4 => 'Fejléc 4'; + + @override + String get heading5 => 'Fejléc 5'; + + @override + String get heading6 => 'Fejléc 6'; + + @override + String get numberedList => 'Számozott lista'; + + @override + String get bulletList => 'Felsorolás'; + + @override + String get checkedList => 'Ellenőrző lista'; + + @override + String get codeBlock => 'Kód blokk'; + + @override + String get quote => 'Idézet'; + + @override + String get increaseIndent => 'Behúzás növelése'; + + @override + String get decreaseIndent => 'Behúzás csökkentése'; + + @override + String get insertURL => 'URL beszúrása'; + + @override + String get visitLink => 'Link megnyitása'; + + @override + String get enterLink => 'Link beírása'; + + @override + String get enterMedia => 'Média beírása'; + + @override + String get edit => 'Szerkesztés'; + + @override + String get apply => 'Alkalmazás'; + + @override + String get hex => 'Hex'; + + @override + String get material => 'Anyag'; + + @override + String get color => 'Szín'; + + @override + String get lineheight => 'Sor magasság'; + + @override + String get findText => 'Szöveg keresése'; + + @override + String get moveToPreviousOccurrence => 'Ugrás az előző előfordulásra'; + + @override + String get moveToNextOccurrence => 'Ugrás a következő előfordulásra'; + + @override + String get savedUsingTheNetwork => 'Mentve hálózaton keresztül'; + + @override + String get savedUsingLocalStorage => 'Mentve helyi tárhelyre'; + + @override + String theImageHasBeenSavedAt(String imagePath) { + return 'A kép elmentve: $imagePath'; + } + + @override + String get errorWhileSavingImage => 'Hiba a kép mentése közben'; + + @override + String get pleaseEnterTextForYourLink => + 'Kérjük, írja be a link szövegét (pl. „További információ”).'; + + @override + String get pleaseEnterTheLinkURL => + 'Kérjük, írja be a link link URL-t (pl. \'https://example.com\')'; + + @override + String get pleaseEnterAValidImageURL => + 'Kérjük, adjon meg egy érvényes kép URL-t'; + + @override + String get pleaseEnterAValidVideoURL => + 'Kérjük, adjon meg egy érvényes videó URL-t'; + + @override + String get photo => 'Fénykép'; + + @override + String get image => 'Kép'; + + @override + String get caseSensitivityAndWholeWordSearch => + 'Nagy- és kisbetűérzékenység és teljes szó keresés'; + + @override + String get caseSensitive => 'Nagy- és kisbetűérzékeny'; + + @override + String get wholeWord => 'Teljes szó'; + + @override + String get insertImage => 'Kép beszúrása'; + + @override + String get pickAPhotoFromYourGallery => + 'Válasszon egy fényképet a galériájából'; + + @override + String get takeAPhotoUsingYourCamera => + 'Készítsen egy fényképet a kamerájával'; + + @override + String get pasteAPhotoUsingALink => 'Illesszen be egy fényképet egy linkkel'; + + @override + String get pickAVideoFromYourGallery => 'Válasszon egy videót a galériájából'; + + @override + String get recordAVideoUsingYourCamera => + 'Vegyen fel egy videót a kamerájával'; + + @override + String get pasteAVideoUsingALink => 'Illesszen be egy videót egy linkkel'; + + @override + String get close => 'Bezárás'; + + @override + String get searchSettings => 'Keresési beállítások'; + + @override + String get cut => 'Kivágás'; + + @override + String get paste => 'Beillesztés'; + + @override + String get insertTable => 'Táblázat beszúrása'; +} diff --git a/lib/src/l10n/quill_hu.arb b/lib/src/l10n/quill_hu.arb new file mode 100644 index 000000000..65895dfed --- /dev/null +++ b/lib/src/l10n/quill_hu.arb @@ -0,0 +1,112 @@ +{ + "@@locale": "hu", + "pasteLink": "Link beillesztése", + "ok": "Ok", + "selectColor": "Szín kiválasztása", + "gallery": "Galéria", + "link": "Link", + "open": "Megnyitás", + "copy": "Másolás", + "remove": "Eltávolítás", + "save": "Mentés", + "zoom": "Nagyítás", + "saved": "Mentve", + "text": "Szöveg", + "resize": "Átméretezés", + "width": "Szélesség", + "height": "Magasság", + "size": "Méret", + "small": "Kicsi", + "large": "Nagy", + "huge": "Óriási", + "clear": "Törlés", + "font": "Betűtípus", + "search": "Keresés", + "camera": "Kamera", + "video": "Videó", + "undo": "Visszavonás", + "redo": "Újra", + "fontFamily": "Betűtípus", + "fontSize": "Betűméret", + "bold": "Félkövér", + "subscript": "Alsó index", + "superscript": "Felső index", + "italic": "Dőlt", + "underline": "Aláhúzás", + "strikeThrough": "Áthúzás", + "inlineCode": "Kód", + "fontColor": "Betűszín", + "backgroundColor": "Háttérszín", + "clearFormat": "Formátum törlése", + "alignLeft": "Balra igazítás", + "alignCenter": "Középre igazítás", + "alignRight": "Jobbra igazítás", + "alignJustify": "Sorkizárt", + "@alignJustify": { + "description": "A szöveg igazítása az ablak teljes szélességében" + }, + "justifyWinWidth": "Sorkizárt ablak szélesség", + "textDirection": "Szöveg irány", + "headerStyle": "Fejléc stílus", + "normal": "Normál", + "heading1": "Fejléc 1", + "heading2": "Fejléc 2", + "heading3": "Fejléc 3", + "heading4": "Fejléc 4", + "heading5": "Fejléc 5", + "heading6": "Fejléc 6", + "numberedList": "Számozott lista", + "bulletList": "Felsorolás", + "checkedList": "Ellenőrző lista", + "codeBlock": "Kód blokk", + "quote": "Idézet", + "increaseIndent": "Behúzás növelése", + "decreaseIndent": "Behúzás csökkentése", + "insertURL": "URL beszúrása", + "visitLink": "Link megnyitása", + "enterLink": "Link beírása", + "enterMedia": "Média beírása", + "edit": "Szerkesztés", + "apply": "Alkalmazás", + "hex": "Hex", + "material": "Anyag", + "color": "Szín", + "lineheight": "Sor magasság", + "findText": "Szöveg keresése", + "moveToPreviousOccurrence": "Ugrás az előző előfordulásra", + "moveToNextOccurrence": "Ugrás a következő előfordulásra", + "savedUsingTheNetwork": "Mentve hálózaton keresztül", + "savedUsingLocalStorage": "Mentve helyi tárhelyre", + "theImageHasBeenSavedAt": "A kép elmentve: {imagePath}", + "@theImageHasBeenSavedAt": { + "description": "Üzenet egy paraméterrel", + "placeholders": { + "imagePath": { + "type": "String", + "example": "path/to/location" + } + } + }, + "errorWhileSavingImage": "Hiba a kép mentése közben", + "pleaseEnterTextForYourLink": "Kérjük, írja be a link szövegét (pl. „További információ”).", + "pleaseEnterTheLinkURL": "Kérjük, írja be a link link URL-t (pl. 'https://example.com')", + "pleaseEnterAValidImageURL": "Kérjük, adjon meg egy érvényes kép URL-t", + "pleaseEnterAValidVideoURL": "Kérjük, adjon meg egy érvényes videó URL-t", + "photo": "Fénykép", + "image": "Kép", + "caseSensitivityAndWholeWordSearch": "Nagy- és kisbetűérzékenység és teljes szó keresés", + "caseSensitive": "Nagy- és kisbetűérzékeny", + "wholeWord": "Teljes szó", + "insertImage": "Kép beszúrása", + "pickAPhotoFromYourGallery": "Válasszon egy fényképet a galériájából", + "takeAPhotoUsingYourCamera": "Készítsen egy fényképet a kamerájával", + "pasteAPhotoUsingALink": "Illesszen be egy fényképet egy linkkel", + "pickAVideoFromYourGallery": "Válasszon egy videót a galériájából", + "recordAVideoUsingYourCamera": "Vegyen fel egy videót a kamerájával", + "pasteAVideoUsingALink": "Illesszen be egy videót egy linkkel", + "close": "Bezárás", + "searchSettings": "Keresési beállítások", + "cut": "Kivágás", + "paste": "Beillesztés", + "insertTable": "Táblázat beszúrása" +} From da1ed15a974983da4a98c9f8d574d53e215084ed Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 27 Sep 2024 21:44:00 +0300 Subject: [PATCH 067/113] fix: replace flutter_keyboard_visibility with flutter_keyboard_visibility_temp_fork to support Flutter/Wasm target (#2293) * fix: replace flutter_keyboard_visibility with flutter_keyboard_visibility_temp_fork to support wasm and be able to target the latest version of compileSdkVersion on Android * fix(example): remove hydrated_bloc to run Flutter/Wasm * fix(wasm): avoid using quill_controller_web_stub.dart for web which will throw exception due to usage of dart.library.html in a conditional check * chore: remove web package as no longer used * chore: add related comments to quill_controller_web_real.dart and quill_controller_web_stub.dart * chore: format quill_controller_web_real.dart and quill_controller_web_stub.dart --- example/lib/main.dart | 10 --- .../settings/cubit/settings_cubit.dart | 14 +--- example/pubspec.yaml | 1 - lib/src/controller/quill_controller.dart | 13 +--- .../web/quill_controller_web_real.dart | 66 ++++++++++--------- .../web/quill_controller_web_stub.dart | 35 +++++----- .../editor/raw_editor/raw_editor_state.dart | 2 +- pubspec.yaml | 3 +- 8 files changed, 59 insertions(+), 85 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 532697a44..499b11bca 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localizations/flutter_localizations.dart' @@ -9,10 +8,6 @@ import 'package:flutter_localizations/flutter_localizations.dart' import 'package:flutter_quill/flutter_quill.dart' show Document; import 'package:flutter_quill/translations.dart' show FlutterQuillLocalizations; import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; -import 'package:hydrated_bloc/hydrated_bloc.dart' - show HydratedBloc, HydratedStorage; -import 'package:path_provider/path_provider.dart' - show getApplicationDocumentsDirectory; import 'screens/home/widgets/home_screen.dart'; import 'screens/quill/quill_screen.dart'; @@ -25,11 +20,6 @@ import 'screens/settings/widgets/settings_screen.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - HydratedBloc.storage = await HydratedStorage.build( - storageDirectory: kIsWeb - ? HydratedStorage.webStorageDirectory - : await getApplicationDocumentsDirectory(), - ); // ignore: deprecated_member_use FlutterQuillExtensions.useSuperClipboardPlugin(); runApp(const MyApp()); diff --git a/example/lib/screens/settings/cubit/settings_cubit.dart b/example/lib/screens/settings/cubit/settings_cubit.dart index ab4937ce3..f577f95c8 100644 --- a/example/lib/screens/settings/cubit/settings_cubit.dart +++ b/example/lib/screens/settings/cubit/settings_cubit.dart @@ -1,25 +1,15 @@ import 'package:flutter/material.dart' show ThemeMode; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:hydrated_bloc/hydrated_bloc.dart' show HydratedCubit; part 'settings_state.dart'; part 'settings_cubit.freezed.dart'; part 'settings_cubit.g.dart'; -class SettingsCubit extends HydratedCubit { +class SettingsCubit extends Cubit { SettingsCubit() : super(const SettingsState()); void updateSettings(SettingsState newSettingsState) { emit(newSettingsState); } - - @override - SettingsState? fromJson(Map json) { - return SettingsState.fromJson(json); - } - - @override - Map? toJson(SettingsState state) { - return state.toJson(); - } } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index b5844399c..1ae5c5a1f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -27,7 +27,6 @@ dependencies: # Bloc libraries bloc: ^8.1.4 flutter_bloc: ^8.1.5 - hydrated_bloc: ^9.1.5 # Freezed freezed_annotation: ^2.4.1 diff --git a/lib/src/controller/quill_controller.dart b/lib/src/controller/quill_controller.dart index 16eae86b7..97a6a5391 100644 --- a/lib/src/controller/quill_controller.dart +++ b/lib/src/controller/quill_controller.dart @@ -1,6 +1,5 @@ import 'dart:math' as math; -import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/services.dart' show ClipboardData, Clipboard; import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart' show experimental; @@ -21,9 +20,6 @@ import '../toolbar/config/simple_toolbar_configurations.dart'; import 'quill_controller_configurations.dart'; import 'quill_controller_rich_paste.dart'; -import 'web/quill_controller_web_stub.dart' - if (dart.library.html) 'web/quill_controller_web_real.dart'; - typedef ReplaceTextCallback = bool Function(int index, int len, Object? data); typedef DeleteCallback = void Function(int cursorPosition, bool forward); @@ -40,11 +36,7 @@ class QuillController extends ChangeNotifier { this.readOnly = false, this.editorFocusNode, }) : _document = document, - _selection = selection { - if (kIsWeb) { - initializeWebPasteEvent(); - } - } + _selection = selection; factory QuillController.basic( {QuillControllerConfigurations configurations = @@ -476,9 +468,6 @@ class QuillController extends ChangeNotifier { } _isDisposed = true; - if (kIsWeb) { - cancelWebPasteEvent(); - } super.dispose(); } diff --git a/lib/src/controller/web/quill_controller_web_real.dart b/lib/src/controller/web/quill_controller_web_real.dart index 017d3510b..629bdc356 100644 --- a/lib/src/controller/web/quill_controller_web_real.dart +++ b/lib/src/controller/web/quill_controller_web_real.dart @@ -1,38 +1,42 @@ +// TODO: This might be removed from here or moved to quill_native_bridge +// commented in https://github.com/singerdmx/flutter-quill/pull/2293 +// removed due to bug https://github.com/singerdmx/flutter-quill/issues/2220 +// added to solve https://github.com/singerdmx/flutter-quill/issues/1998#issuecomment-2361599854 + // This file should not be exported as the APIs in it are meant for internal usage only -import 'dart:async' show StreamSubscription; +// import 'dart:async' show StreamSubscription; -import 'package:web/web.dart'; +// import 'package:web/web.dart'; -import '../quill_controller.dart'; -// ignore: unused_import -import '../quill_controller_rich_paste.dart'; +// import '../quill_controller.dart'; +// // ignore: unused_import +// import '../quill_controller_rich_paste.dart'; -/// Paste event for the web. -/// -/// Will be `null` when [QuillControllerWeb.initializeWebPasteEvent] was not called -/// or the subscription was canceled due to calling [QuillControllerWeb.cancelWebPasteEvent] -/// -/// See: https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event -StreamSubscription? _webPasteEventSubscription; +// /// Paste event for the web. +// /// +// /// Will be `null` when [QuillControllerWeb.initializeWebPasteEvent] was not called +// /// or the subscription was canceled due to calling [QuillControllerWeb.cancelWebPasteEvent] +// /// +// /// See: https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event +// StreamSubscription? _webPasteEventSubscription; -extension QuillControllerWeb on QuillController { - void initializeWebPasteEvent() { - _webPasteEventSubscription = - EventStreamProviders.pasteEvent.forTarget(window.document).listen((e) { - // TODO: See if we can support markdown paste - final html = e.clipboardData?.getData('text/html'); - if (html == null) { - return; - } - // TODO: Temporarily disable the rich text pasting feature as a workaround - // due to issue https://github.com/singerdmx/flutter-quill/issues/2220 - // pasteHTML(html: html); - }); - } +// extension QuillControllerWeb on QuillController { +// void initializeWebPasteEvent() { +// _webPasteEventSubscription = +// EventStreamProviders.pasteEvent.forTarget(window.document).listen((e) { +// final html = e.clipboardData?.getData('text/html'); +// if (html == null) { +// return; +// } +// // TODO: Temporarily disable the rich text pasting feature as a workaround +// // due to issue https://github.com/singerdmx/flutter-quill/issues/2220 +// // pasteHTML(html: html); +// }); +// } - void cancelWebPasteEvent() { - _webPasteEventSubscription?.cancel(); - _webPasteEventSubscription = null; - } -} +// void cancelWebPasteEvent() { +// _webPasteEventSubscription?.cancel(); +// _webPasteEventSubscription = null; +// } +// } diff --git a/lib/src/controller/web/quill_controller_web_stub.dart b/lib/src/controller/web/quill_controller_web_stub.dart index 0f2e41189..73becca63 100644 --- a/lib/src/controller/web/quill_controller_web_stub.dart +++ b/lib/src/controller/web/quill_controller_web_stub.dart @@ -1,20 +1,23 @@ -// This file should not be exported as the APIs in it are meant for internal usage only +// See quill_controller_web_real.dart if you want to know why this is not removed yet +// will be addressed in future releases. -import '../quill_controller.dart'; +// // This file should not be exported as the APIs in it are meant for internal usage only -// This is a mock implementation to compile the app on non-web platforms. -// The real implementation is quill_controller_web_real.dart +// import '../quill_controller.dart'; -extension QuillControllerWeb on QuillController { - void initializeWebPasteEvent() { - throw UnsupportedError( - 'The initializeWebPasteEvent() method should be called only on web.', - ); - } +// // This is a mock implementation to compile the app on non-web platforms. +// // The real implementation is quill_controller_web_real.dart - void cancelWebPasteEvent() { - throw UnsupportedError( - 'The closeWebPasteEvent() method should be called only on web.', - ); - } -} +// extension QuillControllerWeb on QuillController { +// void initializeWebPasteEvent() { +// throw UnsupportedError( +// 'The initializeWebPasteEvent() method should be called only on web.', +// ); +// } + +// void cancelWebPasteEvent() { +// throw UnsupportedError( +// 'The closeWebPasteEvent() method should be called only on web.', +// ); +// } +// } diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index a02aa87d1..b2c0d044e 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -10,7 +10,7 @@ import 'package:flutter/rendering.dart' show RenderAbstractViewport; import 'package:flutter/scheduler.dart' show SchedulerBinding; import 'package:flutter/services.dart' show Clipboard, HardwareKeyboard, SystemChannels, TextInputControl; -import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart' +import 'package:flutter_keyboard_visibility_temp_fork/flutter_keyboard_visibility_temp_fork.dart' show KeyboardVisibilityController; import '../../common/structs/horizontal_spacing.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 92bde70ac..5454b4ae1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -50,7 +50,6 @@ dependencies: equatable: ^2.0.5 meta: ^1.10.0 html: ^0.15.4 - web: ^1.0.0 flutter_colorpicker: ^1.1.0 @@ -61,7 +60,7 @@ dependencies: # Plugins url_launcher: ^6.2.4 - flutter_keyboard_visibility: ^6.0.0 + flutter_keyboard_visibility_temp_fork: ^0.1.1 quill_native_bridge: '>=10.5.14 <=10.6.2' dev_dependencies: From 65eadbfb6a2bfe10a3b4ff8195cc1b240610ffe2 Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 27 Sep 2024 22:44:40 +0300 Subject: [PATCH 068/113] chore: remove dart_quill_delta directory to move it outside of the repo (#2294) --- .github/workflows/main.yml | 3 - .github/workflows/publish.yml | 4 - dart_quill_delta/.gitignore | 7 - dart_quill_delta/CHANGELOG.md | 3115 ----------------- dart_quill_delta/LICENSE | 21 - dart_quill_delta/README.md | 2 - dart_quill_delta/analysis_options.yaml | 30 - .../example/dart_quill_delta_example.dart | 1 - dart_quill_delta/lib/dart_quill_delta.dart | 5 - dart_quill_delta/lib/src/delta/delta.dart | 563 --- .../lib/src/delta/delta_iterator.dart | 100 - .../lib/src/operation/operation.dart | 171 - dart_quill_delta/pubspec.yaml | 20 - .../test/dart_quill_delta_test.dart | 11 - doc/delta_introduction.md | 12 +- example/pubspec.yaml | 2 - scripts/packages.dart | 1 - 17 files changed, 6 insertions(+), 4062 deletions(-) delete mode 100644 dart_quill_delta/.gitignore delete mode 100644 dart_quill_delta/CHANGELOG.md delete mode 100644 dart_quill_delta/LICENSE delete mode 100644 dart_quill_delta/README.md delete mode 100644 dart_quill_delta/analysis_options.yaml delete mode 100644 dart_quill_delta/example/dart_quill_delta_example.dart delete mode 100644 dart_quill_delta/lib/dart_quill_delta.dart delete mode 100644 dart_quill_delta/lib/src/delta/delta.dart delete mode 100644 dart_quill_delta/lib/src/delta/delta_iterator.dart delete mode 100644 dart_quill_delta/lib/src/operation/operation.dart delete mode 100644 dart_quill_delta/pubspec.yaml delete mode 100644 dart_quill_delta/test/dart_quill_delta_test.dart diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f96c90d41..aefda4b23 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,9 +26,6 @@ jobs: - name: 📥 Install Flutter dependencies run: flutter pub get - - - name: 📦 Install dart_quill_delta dependencies - run: flutter pub get -C dart_quill_delta - name: 📦 Install flutter_quill_extensions dependencies run: flutter pub get -C flutter_quill_extensions diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ad73c5823..3a98c5656 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -92,10 +92,6 @@ jobs: - name: 📤 Publish flutter_quill run: flutter pub publish --force - - - name: 📤 Publish dart_quill_delta - run: flutter pub publish --force - working-directory: ./dart_quill_delta/ - name: 📤 Publish flutter_quill_extensions run: flutter pub publish --force diff --git a/dart_quill_delta/.gitignore b/dart_quill_delta/.gitignore deleted file mode 100644 index 3cceda557..000000000 --- a/dart_quill_delta/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# https://dart.dev/guides/libraries/private-files -# Created by `dart pub` -.dart_tool/ - -# Avoid committing pubspec.lock for library packages; see -# https://dart.dev/guides/libraries/private-files#pubspeclock. -pubspec.lock diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md deleted file mode 100644 index ff9e817c8..000000000 --- a/dart_quill_delta/CHANGELOG.md +++ /dev/null @@ -1,3115 +0,0 @@ - - -# Changelog - -All notable changes to this project will be documented in this file. - -## 10.8.0 - -> [!CAUTION] -> This release can be breaking change for `flutter_quill_extensions` users as it remove the built-in support for loading YouTube videos - -If you're using [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) then this release, can be a breaking change for you if you load videos in the editor and expect YouTube videos to be supported, [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) and [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) are no longer dependencies of the extensions package, which are used to support loading YouTube Iframe videos on non-web platforms, more details about the discussion and reasons in [#2286](https://github.com/singerdmx/flutter-quill/pull/2286) and [#2284](https://github.com/singerdmx/flutter-quill/issues/2284). - -We have added an experimental property that gives you more flexibility and control about the implementation you want to use for loading videos. - -> [!WARNING] -> It's likely to experience some common issues while implementing this feature, especially on desktop platforms as the support for [flutter_inappwebview_windows](https://pub.dev/packages/flutter_inappwebview_windows) and [flutter_inappwebview_macos](https://pub.dev/packages/flutter_inappwebview_macos) before 2 days. Some of the issues are in the Flutter Quill editor. - -If you want loading YouTube videos to be a feature again with the latest version of Flutter Quill, you can use an existing plugin or package, or implement your own solution. For example, you might use [`youtube_video_player`](https://pub.dev/packages/youtube_video_player) or [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter), which was previously used in [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions). - -Here’s an example setup using `youtube_player_flutter`: - -```shell -flutter pub add youtube_player_flutter -``` - -Example widget configuration: - -```dart -import 'package:flutter/material.dart'; -import 'package:youtube_player_flutter/youtube_player_flutter.dart'; - -class YoutubeVideoPlayer extends StatefulWidget { - const YoutubeVideoPlayer({required this.videoUrl, super.key}); - - final String videoUrl; - - @override - State createState() => _YoutubeVideoPlayerState(); -} - -class _YoutubeVideoPlayerState extends State { - late final YoutubePlayerController _youtubePlayerController; - @override - void initState() { - super.initState(); - _youtubePlayerController = YoutubePlayerController( - initialVideoId: YoutubePlayer.convertUrlToId(widget.videoUrl) ?? - (throw StateError('Expect a valid video URL')), - flags: const YoutubePlayerFlags( - autoPlay: true, - mute: true, - ), - ); - } - - @override - Widget build(BuildContext context) { - return YoutubePlayer( - controller: _youtubePlayerController, - showVideoProgressIndicator: true, - ); - } - - @override - void dispose() { - _youtubePlayerController.dispose(); - super.dispose(); - } -} - -``` - -Then, integrate it with `QuillEditorVideoEmbedConfigurations` - -```dart -FlutterQuillEmbeds.editorBuilders( - videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations( - customVideoBuilder: (videoUrl, readOnly) { - // Example: Check for YouTube Video URL and return your - // YouTube video widget here. - bool isYouTubeUrl(String videoUrl) { - try { - final uri = Uri.parse(videoUrl); - return uri.host == 'www.youtube.com' || - uri.host == 'youtube.com' || - uri.host == 'youtu.be' || - uri.host == 'www.youtu.be'; - } catch (_) { - return false; - } - } - - if (isYouTubeUrl(videoUrl)) { - return YoutubeVideoPlayer( - videoUrl: videoUrl, - ); - } - - // Return null to fallback to the default logic - return null; - }, - ignoreYouTubeSupport: true, - ), -); -``` - -> [!NOTE] -> This example illustrates a basic approach, additional adjustments might be necessary to meet your specific needs. YouTube video support is no longer included in this project. Keep in mind that `customVideoBuilder` is experimental and can change without being considered as breaking change. More details in [breaking changes](https://github.com/singerdmx/flutter-quill#-breaking-changes) section. - -[`super_clipboard`](https://pub.dev/packages/super_clipboard) will also no longer a dependency of `flutter_quill_extensions` once [PR #2230](https://github.com/singerdmx/flutter-quill/pull/2230) is ready. - -We're looking forward to your feedback. - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.7...v10.8.0 - -## 10.7.7 - -This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230) - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.6...v10.7.7 - -## 10.7.6 - -* Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267 -* docs: add important note for contributors before introducing new features by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2269 -* docs(readme): add 'Breaking Changes' section by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2275 -* Fix: Resolved issue with broken IME composing rect in Windows desktop(re-implementation) by @agata in https://github.com/singerdmx/flutter-quill/pull/2282 - -## New Contributors -* @Luismi74 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2267 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.5...v10.7.6 - -## 10.7.5 - -* fix(ci): add flutter pub get step for quill_native_bridge by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2265 -* revert: "Resolved issue with broken IME composing rect in Windows desktop" by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2266 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.4...v10.7.5 - -## 10.7.4 - -* chore: remove pubspec_overrides.yaml and pubspec_overrides.yaml.disabled by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2262 -* ci: remove quill_native_bridge from automated publishing workflow by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2263 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.3...v10.7.4 - -## 10.7.3 - -- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` -- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code. - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3 - -## 10.7.2 - -## What's Changed -* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258 - -This is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`. - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2 - -## 10.7.1 - -* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 -* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1 - -## 10.7.0 - -* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0 - -## 10.6.6 - -* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 - -## New Contributors -* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6 - -## 10.6.5 - -* Refine IME composing range styling by applying underline as text style by @agata in https://github.com/singerdmx/flutter-quill/pull/2244 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.4...v10.6.5 - -## 10.6.4 - -* fix: the composing text did not show an underline during IME conversion by @agata in https://github.com/singerdmx/flutter-quill/pull/2242 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.3...v10.6.4 - -## 10.6.3 - -* Fix: Resolved issue with broken IME composing rect in Windows desktop by @agata in https://github.com/singerdmx/flutter-quill/pull/2239 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.2...v10.6.3 - -## 10.6.2 - -* Fix: QuillToolbarToggleStyleButton Switching failure by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2234 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.1...v10.6.2 - -## 10.6.1 - -* Chore: update `flutter_quill_delta_from_html` to remove exception calls by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2232 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.0...v10.6.1 - -## 10.6.0 - -* docs: cleanup the docs, remove outdated resources, general changes by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2227 -* Feat: customizable character and space shortcut events by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2228 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.19...v10.6.0 - -## 10.5.19 - -* fix: properties other than 'style' for custom inline code styles (such as 'backgroundColor') were not being applied correctly by @agata in https://github.com/singerdmx/flutter-quill/pull/2226 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.18...v10.5.19 - -## 10.5.18 - -* feat(web): rich text paste from Clipboard using HTML by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2009 -* revert: disable rich text paste feature on web as a workaround by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2221 -* refactor: moved shortcuts and onKeyEvents to its own file by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2223 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.17...v10.5.18 - -## 10.5.17 - -* feat(l10n): localize all untranslated.json by @erdnx in https://github.com/singerdmx/flutter-quill/pull/2217 -* Fix: Block Attributes are not displayed if the editor is empty by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2210 - -## New Contributors -* @erdnx made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2217 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.16...v10.5.17 - -## 10.5.16 - -* chore: remove device_info_plus and add quill_native_bridge to access platform specific APIs by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2194 -* Not show/update/hiden mangnifier when manifier config is disbale by @demoYang in https://github.com/singerdmx/flutter-quill/pull/2212 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.14...v10.5.16 - -## 10.5.15-dev.0 - -Introduce `quill_native_bridge` which is an internal plugin to use by `flutter_quill` to access platform APIs. - -For now, the only functionality it supports is to check whatever the iOS app is running on iOS simulator without requiring [`device_info_plus`](pub.dev/packages/device_info_plus) as a dependency. - -> [!NOTE] -> `quill_native_bridge` is a plugin for internal use and should not be used in production applications -> as breaking changes can happen and can removed at any time. - -For more details and discussion see [#2194](https://github.com/singerdmx/flutter-quill/pull/2194). - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.14...v10.5.15-dev.0 - -## 10.5.14 - -* chore(localization): add Greek language support by @DKalathas in https://github.com/singerdmx/flutter-quill/pull/2206 - -## New Contributors -* @DKalathas made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2206 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.13...v10.5.14 - -## 10.5.13 - -* Revert "Fix: Allow backspace at start of document to remove block style and header style by @agata in https://github.com/singerdmx/flutter-quill/pull/2201 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.12...v10.5.13 - -## 10.5.12 - -* Fix: Backspace remove block attributes at start by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2200 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.11...v10.5.12 - -## 10.5.11 - -* Enhancement: Backspace handling at the start of blocks in delete rules by @agata in https://github.com/singerdmx/flutter-quill/pull/2199 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.10...v10.5.11 - -## 10.5.10 - -* Allow backspace at start of document to remove block style and header style by @agata in https://github.com/singerdmx/flutter-quill/pull/2198 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.9...v10.5.10 - -## 10.5.9 - -* chore: improve platform check by using constants and defaultTargetPlatform by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2188 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.8...v10.5.9 - -## 10.5.8 - -* Feat: Add configuration option to always indent on TAB key press by @agata in https://github.com/singerdmx/flutter-quill/pull/2187 - -## New Contributors -* @agata made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2187 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.7...v10.5.8 - -## 10.5.7 - -* chore(example): downgrade Kotlin from 1.9.24 to 1.7.10 by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2185 -* style: refactor build leading function style, width, and padding parameters for custom node leading builder by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2182 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.6...v10.5.7 - -## 10.5.6 - -* chore(deps): update super_clipboard to 0.8.20 in flutter_quill_extensions by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2181 -* Update quill_screen.dart, i chaged the logic for showing a lock when … by @rightpossible in https://github.com/singerdmx/flutter-quill/pull/2183 - -## New Contributors -* @rightpossible made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2183 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.5...v10.5.6 - -## 10.5.5 - -* Fix text selection handles when scroll mobile by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2176 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.4...v10.5.5 - -## 10.5.4 - -* Add Thai (th) localization by @silkyland in https://github.com/singerdmx/flutter-quill/pull/2175 - -## New Contributors -* @silkyland made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2175 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.3...v10.5.4 - -## 10.5.3 - -* Fix: Assertion Failure in line.dart When Editing Text with Block-Level Attributes by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2174 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.2...v10.5.3 - -## 10.5.2 - -* fix(toolbar): regard showDividers in simple toolbar by @realth000 in https://github.com/singerdmx/flutter-quill/pull/2172 - -## New Contributors -* @realth000 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2172 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.1...v10.5.2 - -## 10.5.1 - -* fix drag selection extension (does not start at tap location if you are dragging quickly by @jezell in https://github.com/singerdmx/flutter-quill/pull/2170 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.0...v10.5.1 - -## 10.5.0 - -* Feat: custom leading builder by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2146 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.9...v10.5.0 - -## 10.4.9 - -* fix floating cursor not disappearing after scroll end by @vishna in https://github.com/singerdmx/flutter-quill/pull/2163 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.8...v10.4.9 - -## 10.4.8 - -* Fix: direction has no opposite effect if the language is rtl by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2154 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.7...v10.4.8 - -## 10.4.7 - -* Fix: Unable to scroll 2nd editor window by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2152 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.6...v10.4.7 - -## 10.4.6 - -* Handle null child query by @jezell in https://github.com/singerdmx/flutter-quill/pull/2151 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.5...v10.4.6 - -## 10.4.5 - -* chore!: move spell checker to example by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2145 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.4...v10.4.5 - -## 10.4.4 - -* fix custom recognizer builder not being passed to editabletextblock by @jezell in https://github.com/singerdmx/flutter-quill/pull/2143 -* fix null reference exception when dragging selection on non scrollable selection by @jezell in https://github.com/singerdmx/flutter-quill/pull/2144 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.3...v10.4.4 - -## 10.4.3 - -* Chore: update simple_spell_checker package by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2139 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.2...v10.4.3 - -## 10.4.2 - -* Revert "fix: Double click to select text sometimes doesn't work. ([#2086](https://github.com/singerdmx/flutter-quill/pull/2086)) - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.1...v10.4.2 - -## 10.4.1 - -* Chore: improve Spell checker API to the example by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2133 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.0...v10.4.1 - -## 10.4.0 - -* Copy TapAndPanGestureRecognizer from TextField by @demoYang in https://github.com/singerdmx/flutter-quill/pull/2128 -* enhance stringToColor with a custom defined palette from `DefaultStyles` by @vishna in https://github.com/singerdmx/flutter-quill/pull/2095 -* Feat: include spell checker for example app by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2127 - -## New Contributors -* @vishna made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2095 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.3.3...v10.4.0 - -## 10.3.2 - -* Fix: Loss of style when backspace by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2125 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.3.1...v10.3.2 - -## 10.3.1 - -* Chore: Move spellchecker service to extensions by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2120 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.3.0...v10.3.1 - -## 10.3.0 - -* Feat: Spellchecker for Flutter Quill by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2118 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.2.1...v10.3.0 - -## 10.2.1 - -* Fix: context menu is visible even when selection is collapsed by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2116 -* Fix: unsafe operation while getting overlayEntry in text_selection by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2117 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.2.0...v10.2.1 - -## 10.2.0 - -* refactor!: restructure project into modular architecture for flutter_quill_extensions by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2106 -* Fix: Link selection and editing by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2114 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.10...v10.2.0 - -## 10.1.10 - -* Fix(example): image_cropper outdated version by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2100 -* Using dart.library.js_interop instead of dart.library.html by @h1376h in https://github.com/singerdmx/flutter-quill/pull/2103 - -## New Contributors -* @h1376h made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2103 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.9...v10.1.10 - -## 10.1.9 - -* restore ability to pass in key to QuillEditor by @mtallenca in https://github.com/singerdmx/flutter-quill/pull/2093 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.8...v10.1.9 - -## 10.1.8 - -* Enhancement: Search within Embed objects by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2090 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.7...v10.1.8 - -## 10.1.7 - -* Feature/allow shortcut override by @InstrinsicAutomations in https://github.com/singerdmx/flutter-quill/pull/2089 - -## New Contributors -* @InstrinsicAutomations made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2089 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.6...v10.1.7 - -## 10.1.6 - -* fixed #1295 Double click to select text sometimes doesn't work. by @li8607 in https://github.com/singerdmx/flutter-quill/pull/2086 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.5...v10.1.6 - -## 10.1.5 - -* ref: add `VerticalSpacing.zero` and `HorizontalSpacing.zero` named constants by @adil192 in https://github.com/singerdmx/flutter-quill/pull/2083 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.4...v10.1.5 - -## 10.1.4 - -* Fix: collectStyles for lists and alignments by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2082 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.3...v10.1.4 - -## 10.1.3 - -* Move Controller outside of configurations data class by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2078 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.2...v10.1.3 - -## 10.1.2 - -* Fix Multiline paste with attributes and embeds by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2074 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.1...v10.1.2 - -## 10.1.1 - -* Toolbar dividers fixes + Docs updates by @troyanskiy in https://github.com/singerdmx/flutter-quill/pull/2071 - -## New Contributors -* @troyanskiy made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2071 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.0...v10.1.1 - -## 10.1.0 - -* Feat: support for customize copy and cut Embeddables to Clipboard by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2067 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.10...v10.1.0 - -## 10.0.10 - -* fix: Hide selection toolbar if editor loses focus by @huandu in https://github.com/singerdmx/flutter-quill/pull/2066 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.9...v10.0.10 - -## 10.0.9 - -* Fix: manual checking of directionality by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2063 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.8...v10.0.9 - -## 10.0.8 - -* feat: add callback to handle performAction by @huandu in https://github.com/singerdmx/flutter-quill/pull/2061 -* fix: Invalid selection when tapping placeholder text by @huandu in https://github.com/singerdmx/flutter-quill/pull/2062 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.7...v10.0.8 - -## 10.0.7 - -* Fix: RTL issues by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2060 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.6...v10.0.7 - -## 10.0.6 - -* fix: textInputAction is not set when creating QuillRawEditorConfiguration by @huandu in https://github.com/singerdmx/flutter-quill/pull/2057 - -## New Contributors -* @huandu made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2057 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.5...v10.0.6 - -## 10.0.5 - -* Add tests for PreserveInlineStylesRule and fix link editing. Other minor fixes. by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2058 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.4...v10.0.5 - -## 10.0.4 - -* Add ability to set up horizontal spacing for block style by @dimkanovikov in https://github.com/singerdmx/flutter-quill/pull/2051 -* add catalan language by @spilioio in https://github.com/singerdmx/flutter-quill/pull/2054 - -## New Contributors -* @dimkanovikov made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2051 -* @spilioio made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2054 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.3...v10.0.4 - -## 10.0.3 - -* doc(Delta): more documentation about Delta by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2042 -* doc(attribute): added documentation about Attribute class and how create one by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2048 -* if magnifier removes toolbar, restore it when it is hidden by @mtallenca in https://github.com/singerdmx/flutter-quill/pull/2049 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.2...v10.0.3 - -## 10.0.2 - -* chore(scripts): migrate the scripts from sh to dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2036 -* Have the ability to create custom rules, closes #1162 by @Guillergood in https://github.com/singerdmx/flutter-quill/pull/2040 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.1...v10.0.2 - -## 10.0.1 - -This release is identical to [10.0.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.0.0) with a fix that addresses issue #2034 by requiring `10.0.0` as the minimum version for quill related dependencies. - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.0...v10.0.1 - -## 10.0.0 - -* refactor: restructure project into modular architecture for flutter_quill by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2032 -* chore: update GitHub PR template by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2033 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.6.0...v10.0.0 - -## 9.6.0 - -* [feature] : quill add magnifier by @demoYang in https://github.com/singerdmx/flutter-quill/pull/2026 - -## New Contributors -* @demoYang made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2026 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.23...v9.6.0 - -## 9.5.23 - -* add untranslated Kurdish keys by @Xoshbin in https://github.com/singerdmx/flutter-quill/pull/2029 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.22...v9.5.23 - -## 9.5.22 - -* Fix outdated contributor guide link on PR template by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2027 -* Fix(rule): PreserveInlineStyleRule assume the type of the operation data and throw stacktrace by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2028 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.21...v9.5.22 - -## 9.5.21 - -* Fix: Key actions not being handled by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2025 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.20...v9.5.21 - -## 9.5.20 - -* Remove useless delta_x_test by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2017 -* Update flutter_quill_delta_from_html package on pubspec.yaml by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2018 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.19...v9.5.20 - -## 9.5.19 - -* fixed #1835 Embed Reloads on Cmd Key Press by @li8607 in https://github.com/singerdmx/flutter-quill/pull/2013 - -## New Contributors -* @li8607 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2013 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.18...v9.5.19 - -## 9.5.18 - -* Refactor: Moved core link button functions to link.dart by @Alspb in https://github.com/singerdmx/flutter-quill/pull/2008 -* doc: more documentation about Rules by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2014 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.17...v9.5.18 - -## 9.5.17 - -* Feat(config): added option to disable automatic list conversion by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2011 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.16...v9.5.17 - -## 9.5.16 - -* chore: drop support for HTML, PDF, and Markdown converting functions by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/1997 -* docs(readme): update the extensions package to document the Rich Text Paste feature on web by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2001 -* Fix(test): delta_x tests fail by wrong expected Delta for video embed by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2010 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.15...v9.5.16 - -## 9.5.15 - -* Update delta_from_html to fix nested lists issues and more by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2000 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.14...v9.5.15 - -## 9.5.14 - -* docs(readme): update 'Conversion to HTML' section to include more details by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/1996 -* Update flutter_quill_delta_from_html on pubspec.yaml to fix current issues by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1999 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.13...v9.5.14 - -## 9.5.13 - -* Added new default ConverterOptions configurations by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1990 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.12...v9.5.13 - -## 9.5.12 - -* fix: Fixed passing textStyle to formula embed by @shubham030 in https://github.com/singerdmx/flutter-quill/pull/1989 - -## New Contributors -* @shubham030 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1989 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.11...v9.5.12 - -## 9.5.11 - -* Update flutter_quill_delta_from_html in pubspec.yaml by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1988 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.10...v9.5.11 - -## 9.5.10 - -* chore: remove dependency html converter by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1987 -* Fix: LineHeight button to use MenuAnchor by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/1986 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.9...v9.5.10 - -## 9.5.9 - -* Update pubspec.yaml to remove html2md by @singerdmx in https://github.com/singerdmx/flutter-quill/pull/1985 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.8...v9.5.9 - -## 9.5.8 - -* fix(typo): fix typo ClipboardServiceProvider.instacne by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1983 -* Feat: New way to get Delta from HTML inputs by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1984 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.7...v9.5.8 - -## 9.5.7 - -* refactor: context menu function, add test code by @n7484443 in https://github.com/singerdmx/flutter-quill/pull/1979 -* Fix: PreserveInlineStylesRule by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/1980 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.6...v9.5.7 - -## 9.5.6 - -* fix: common link is detected as a video link by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1978 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.5...v9.5.6 - -## 9.5.5 - -* fix: context menu behavior in mouse, desktop env by @n7484443 in https://github.com/singerdmx/flutter-quill/pull/1976 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.4...v9.5.5 - -## 9.5.4 - -* Feat: Line height support by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1972 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.3...v9.5.4 - -## 9.5.3 - -* Perf: Performance optimization by @Alspb in https://github.com/singerdmx/flutter-quill/pull/1964 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.2...v9.5.3 - -## 9.5.2 - -* Fix style settings by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/1962 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.1...v9.5.2 - -## 9.5.1 - -* feat(extensions): Youtube Video Player Support Mode by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1916 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.0...v9.5.1 - -## 9.5.0 - -* Partial support for table embed by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1960 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.9...v9.5.0 - -## 9.4.9 - -* Upgrade photo_view to 0.15.0 for flutter_quill_extensions by @singerdmx in https://github.com/singerdmx/flutter-quill/pull/1958 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.8...v9.4.9 - -## 9.4.8 - -* Add support for html underline and videos by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1955 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.7...v9.4.8 - -## 9.4.7 - -* fixed #1953 italic detection error by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1954 - -## New Contributors -* @CatHood0 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1954 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.6...v9.4.7 - -## 9.4.6 - -* fix: search dialog throw an exception due to missing FlutterQuillLocalizations.delegate in the editor by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1938 -* fix(editor): implement editor shortcut action for home and end keys to fix exception about unimplemented ScrollToDocumentBoundaryIntent by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1937 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.5...v9.4.6 - -## 9.4.5 - -* fix: color picker hex unfocus on web by @geronimol in https://github.com/singerdmx/flutter-quill/pull/1934 - -## New Contributors -* @geronimol made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1934 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.4...v9.4.5 - -## 9.4.4 - -* fix: Enabled link regex to be overridden by @JoepHeijnen in https://github.com/singerdmx/flutter-quill/pull/1931 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.3...v9.4.4 - -## 9.4.3 - -* Fix: setState() called after dispose(): QuillToolbarClipboardButtonState #1895 by @windows7lake in https://github.com/singerdmx/flutter-quill/pull/1926 - -## New Contributors -* @windows7lake made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1926 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.2...v9.4.3 - -## 9.4.2 - -* Respect autofocus, closes #1923 by @Guillergood in https://github.com/singerdmx/flutter-quill/pull/1924 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.1...v9.4.2 - -## 9.4.1 - -* replace base64 regex string by @salba360496 in https://github.com/singerdmx/flutter-quill/pull/1919 - -## New Contributors -* @salba360496 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1919 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.0...v9.4.1 - -## 9.4.0 - -This release can be used without changing anything, although it can break the behavior a little, we provided a way to use the old behavior in `9.3.x` - -- Thanks to @Alspb, the search bar/dialog has been reworked for improved UI that fits **Material 3** look and feel, the search happens on the fly, and other minor changes, if you want the old search bar, you can restore it with one line if you're using `QuillSimpleToolbar`: - ```dart - QuillToolbar.simple( - configurations: QuillSimpleToolbarConfigurations( - searchButtonType: SearchButtonType.legacy, - ), - ) - ``` - While the changes are mostly to the `QuillToolbarSearchDialog` and it seems this should be `searchDialogType`, we provided the old button with the old dialog in case we update the button in the future. - - If you're using `QuillToolbarSearchButton` in a custom Toolbar, you don't need anything to get the new button. if you want the old button, use the `QuillToolbarLegacySearchButton` widget - - Consider using the improved button with the improved dialog as the legacy button might removed in future releases (for now, it's not deprecated) - -
- Before - - ![image](https://github.com/singerdmx/flutter-quill/assets/73608287/9b40ad03-717f-4518-95f1-8d9cad773b2b) - - -
- -
- Improved - - ![image](https://github.com/singerdmx/flutter-quill/assets/73608287/e581733d-63fa-4984-9c41-4a325a0a0c04) - -
- - For the detailed changes, see #1904 - -- Korean translations by @leegh519 in https://github.com/singerdmx/flutter-quill/pull/1911 - -- The usage of `super_clipboard` plugin in `flutter_quill` has been moved to the `flutter_quill_extensions` package, this will restore the old behavior in `8.x.x` though it will break the `onImagePaste`, `onGifPaste` and rich text pasting from HTML or Markdown, most of those features are available in `super_clipboard` plugin except `onImagePaste` which was available as we were using [pasteboard](https://pub.dev/packages/pasteboard), Unfortunately, it's no longer supported on recent versions of Flutter, and some functionalities such as an image from Clipboard and Html paste are not supported on some platforms such as Android, your project will continue to work, calls of `onImagePaste` and `onGifPaste` will be ignored unless you include [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) package in your project and call: - - ```dart - FlutterQuillExtensions.useSuperClipboardPlugin(); - ``` - Before using any `flutter_quill` widgets, this will restore the old behavior in `9.x.x` - - We initially wanted to publish `flutter_quill_super_clipboard` to allow: - - Using `super_clipboard` without `flutter_quill_extensions` packages and plugins - - Using `flutter_quill_extensions` with optional `super_clipboard` - - To simplify the usage, we moved it to `flutter_quill_extensions`, let us know if you want any of the use cases above. - - Overall `super_clipboard` is a Comprehensive clipboard plugin with a lot of features, the only thing that developers didn't want is Rust installation even though it's automated. - - The main goal of `ClipboardService` is to make `super_clipboard` optional, you can use your own implementation, and create a class that implements `ClipboardService`, which you can get by: - ```dart - // ignore: implementation_imports - import 'package:flutter_quill/src/services/clipboard/clipboard_service.dart'; - ``` - - Then you can call: - ```dart - // ignore: implementation_imports -import 'package:flutter_quill/src/services/clipboard/clipboard_service_provider.dart'; - ClipboardServiceProvider.setInstance(YourClipboardService()); -``` - - The interface could change at any time and will be updated internally for `flutter_quill` and `flutter_quill_extensions`, we didn't export those two classes by default to avoid breaking changes in case you use them as we might change them in the future. - - If you use the above imports, you might get **breaking changes** in **non-breaking change releases**. - -- Subscript and Superscript should now work for all languages and characters - - The previous implementation required the Apple 'SF-Pro-Display-Regular.otf' font which is only licensed/permitted for use on Apple devices. -We have removed the Apple font from the example - -- Allow pasting Markdown and HTML file content from the system to the editor - - Before `9.4.x` if you try to copy an HTML or Markdown file, and paste it into the editor, you will get the file name in the editor - Copying an HTML file, or HTML content from apps and websites is different than copying plain text. - - This is why this change requires `super_clipboard` implementation as this is platform-dependent: - ```dart - FlutterQuillExtensions.useSuperClipboardPlugin(); - ``` - as mentioned above. - - The following example for copying a Markdown file: - -
- Markdown File Content - - ```md - - **Note**: This package supports converting from HTML back to Quill delta but it's experimental and used internally when pasting HTML content from the clipboard to the Quill Editor - - You have two options: - - 1. Using [quill_html_converter](./quill_html_converter/) to convert to HTML, the package can convert the Quill delta to HTML well - (it uses [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html)), it is just a handy extension to do it more quickly - 1. Another option is to use - [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html) to convert your document - to HTML. - This package has full support for all Quill operations—including images, videos, formulas, - tables, and mentions. - Conversion can be performed in vanilla Dart (i.e., server-side or CLI) or in Flutter. - It is a complete Dart part of the popular and mature [quill-delta-to-html](https://www.npmjs.com/package/quill-delta-to-html) - Typescript/Javascript package. - this package doesn't convert the HTML back to Quill Delta as far as we know - - ``` - -
- -
- Before - - ![image](https://github.com/singerdmx/flutter-quill/assets/73608287/03f5ae20-796c-4e8b-8668-09a994211c1e) - -
- -
- After - - ![image](https://github.com/singerdmx/flutter-quill/assets/73608287/7e3a1987-36e7-4665-944a-add87d24e788) - -
- - Markdown, and HTML converting from and to Delta are **currently far from perfect**, the current implementation could improved a lot - however **it will likely not work like expected**, due to differences between HTML and Delta, see this [comment](https://github.com/slab/quill/issues/1551#issuecomment-311458570) for more info. - - ![Copying Markdown file into Flutter Quill Editor](https://github.com/singerdmx/flutter-quill/assets/73608287/63bd6ba6-cc49-4335-84dc-91a0fa5c95a9) - - For more details see #1915 - - Using or converting to HTML or Markdown is highly experimental and shouldn't be used for production applications. - - We use it internally as it is more suitable for our specific use case., copying content from external websites and pasting it into the editor - previously breaks the styles, while the current implementation is not ready, it provides a better user experience and doesn't have many downsides. - - Feel free to report any bugs or feature requests at [Issues](https://github.com/singerdmx/flutter-quill/issues) or drop any suggestions and questions at [Discussions](https://github.com/singerdmx/flutter-quill/discussions) - -## New Contributors -* @leegh519 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1911 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.21...v9.4.0 - -## 9.3.21 - -* fix: assertion failure for swipe typing and undo on Android by @crasowas in https://github.com/singerdmx/flutter-quill/pull/1898 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.20...v9.3.21 - -## 9.3.20 - -* Fix: Issue 1887 by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/1892 -* fix: toolbar style change will be invalid when inputting more than 2 characters at a time by @crasowas in https://github.com/singerdmx/flutter-quill/pull/1890 - -## New Contributors -* @crasowas made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1890 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.19...v9.3.20 - -## 9.3.19 - -* Fix reported issues by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/1886 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.18...v9.3.19 - -## 9.3.18 - -* Fix: Undo/redo cursor position fixed by @Alspb in https://github.com/singerdmx/flutter-quill/pull/1885 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.17...v9.3.18 - -## 9.3.17 - -* Update super_clipboard plugin to 0.8.15 to address [#1882](https://github.com/singerdmx/flutter-quill/issues/1882) - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.16...v9.3.17 - -## 9.3.16 - -* Update `lint` dev package to 4.0.0 -* Require at least version 0.8.13 of the plugin - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.15...v9.3.16 - -## 9.3.15 - - -* Ci/automate updating the files by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1879 -* Updating outdated README.md and adding a few guidelines for CONTRIBUTING.md - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.14...v9.3.15 - -## 9.3.14 - -* Chore/use original color picker package in [#1877](https://github.com/singerdmx/flutter-quill/pull/1877) - -## 9.3.13 - -* fix: `readOnlyMouseCursor` losing in construction function -* Fix block multi-line selection style - -## 9.3.12 - -* Add `readOnlyMouseCursor` to config mouse cursor type - -## 9.3.11 - -* Fix typo in QuillHtmlConverter -* Fix re-create checkbox - -## 9.3.10 - -* Support clipboard actions from the toolbar - -## 9.3.9 - -* fix: MD Parsing for multi space -* fix: FontFamily and FontSize toolbars track the text selected in the editor -* feat: Add checkBoxReadOnly property which can override readOnly for checkbox - -## 9.3.8 - -* fix: removed misleading parameters -* fix: added missed translations for ru, es, de -* added translations for Nepali Locale('ne', 'NP') - -## 9.3.7 - -* Fix for keyboard jumping when switching focus from a TextField -* Toolbar button styling to reflect cursor position when running on desktops with keyboard to move care - -## 9.3.6 - -* Add SK and update CS locales [#1796](https://github.com/singerdmx/flutter-quill/pull/1796) -* Fixes: - * QuillIconTheme changes for FontFamily and FontSize buttons are not applied [#1797](https://github.com/singerdmx/flutter-quill/pull/1796) - * Make the arrow_drop_down icons in the QuillToolbar the same size for all MenuAnchor buttons [#1799](https://github.com/singerdmx/flutter-quill/pull/1796) - -## 9.3.5 - -* Update the minimum version for the packages to support `device_info_plus` version 10.0.0 [#1783](https://github.com/singerdmx/flutter-quill/issues/1783) -* Update the minimum version for `youtube_player_flutter` to new major version 9.0.0 in the `flutter_quill_extensions` - -## 9.3.4 - -* fix: multiline styling stuck/not working properly [#1782](https://github.com/singerdmx/flutter-quill/pull/1782) - -## 9.3.3 - -* Update `quill_html_converter` versions - -## 9.3.2 - -* Fix dispose of text painter [#1774](https://github.com/singerdmx/flutter-quill/pull/1774) - -## 9.3.1 - -* Require Flutter 3.19.0 as minimum version - -## 9.3.0 - -* **Breaking change**: `Document.fromHtml(html)` is now returns `Document` instead of `Delta`, use `DeltaX.fromHtml` to return `Delta` -* Update old deprecated api from Flutter 3.19 -* Scribble scroll fix by @mtallenca in https://github.com/singerdmx/flutter-quill/pull/1745 - -## 9.2.14 - -* feat: move cursor after inserting video/image -* Apple pencil - -## 9.2.13 - -* Fix crash with inserting text from contextMenuButtonItems -* Fix incorrect behaviour of context menu -* fix: selection handles behaviour and unnessesary style assert -* Update quill_fr.arb - -## 9.2.12 - -* Fix safari clipboard bug -* Add the option to disable clipboard functionality - -## 9.2.11 - -* Fix a bug where it has problems with pasting text into the editor when the clipboard has styled text - -## 9.2.10 - -* Update example screenshots -* Refactor `Container` to `QuillContainer` with backward compatibility -* A workaround fix in history feature - -## 9.2.9 - -* Refactor the type of `Delta().toJson()` to be more clear type - -## 9.2.8 - -* feat: Export Container node as QuillContainer -* fix web cursor position / height (don't use iOS logic) -* Added Swedish translation - -## 9.2.6 - -* [fix selection.affinity always downstream after updateEditingValue](https://github.com/singerdmx/flutter-quill/pull/1682) -* Bumb version of `super_clipboard` - -## 9.2.5 - -* Bumb version of `super_clipboard` - -## 9.2.4 - -* Use fixed version of intl - -## 9.2.3 - -* remove unncessary column in Flutter quill video embed block - -## 9.2.2 - -* Fix bug [#1627](https://github.com/singerdmx/flutter-quill/issues/1627) - -## 9.2.1 - -* Fix [bug](https://github.com/singerdmx/flutter-quill/issues/1119#issuecomment-1872605246) with font size button -* Added ro RO translations -* 📖 Update zh, zh_CN translations - -## 9.2.0 - -* Require minimum version `6.0.0` of `flutter_keyboard_visibility` to fix some build issues with Android Gradle Plugin 8.2.0 -* Add on image clicked in `flutter_quill_extensions` callback -* Deprecate `globalIconSize` and `globalIconButtonFactor`, use `iconSize` and `iconButtonFactor` instead -* Fix the `QuillToolbarSelectAlignmentButtons` - -## 9.1.1 - -* Require `super_clipboard` minimum version `0.8.1` to fix some bug with Linux build failure - -## 9.1.1-dev - -* Fix bug [#1636](https://github.com/singerdmx/flutter-quill/issues/1636) -* Fix a where you paste styled content (HTML) it always insert a new line at first even if the document is empty -* Fix the font size button and migrate to `MenuAnchor` -* The `defaultDisplayText` is no longer required in the font size and header dropdown buttons -* Add pdf converter in a new package (`quill_pdf_converter`) - -## 9.1.0 - -* Fix the simple toolbar by add properties of `IconButton` and fix some buttons - -## 9.1.0-dev.2 - -* Fix the history buttons - -## 9.1.0-dev.1 - -* Bug fixes in the simple toolbar buttons - -## 9.1.0-dev - -* **Breaking Change**: in the `QuillSimpleToolbar` Fix the `QuillIconTheme` by replacing all the properties with two properties of type `ButtonStyle`, use `IconButton.styleFrom()` - -## 9.0.6 - -* Fix bug in QuillToolbarSelectAlignmentButtons - -## 9.0.5 - -* You can now use most of the buttons without internal provider - -## 9.0.4 - -* Feature: [#1611](https://github.com/singerdmx/flutter-quill/issues/1611) -* Export missing widgets - -## 9.0.3 - -* Flutter Quill Extensions: - * Fix file image support for web image emebed builder - -## 9.0.2 - -* Remove unused properties in the `QuillToolbarSelectHeaderStyleDropdownButton` -* Fix the `QuillSimpleToolbar` when `useMaterial3` is false, please upgrade to the latest version of flutter for better support - -## 9.0.2-dev.3 - -* Export `QuillSingleChildScrollView` - -## 9.0.2-dev.2 - -* Add the new translations for ru, uk arb files by [#1575](https://github.com/singerdmx/flutter-quill/pull/1575) -* Add a new dropdown button by [#1575](https://github.com/singerdmx/flutter-quill/pull/1575) -* Update the default style values by [#1575](https://github.com/singerdmx/flutter-quill/pull/1575) -* Fix bug [#1562](https://github.com/singerdmx/flutter-quill/issues/1562) -* Fix the second bug of [#1480](https://github.com/singerdmx/flutter-quill/issues/1480) - -## 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 -* Add `toolbarRunSpacing` property to the simple toolbar - -## 9.0.1 - -* Fix default icon size - -## 9.0.0 - -* This version is quite stable but it's not how we wanted to be, because the lack of time and there are not too many maintainers active, we decided to publish it, we might make a new breaking changes verion - -## 9.0.1-dev.1 - -* Flutter Quill Extensions: - * Update `QuillImageUtilities` and fixining some bugs - -## 9.0.1-dev - -* Test new GitHub workflows - -## 9.0.0-dev-10 - -* Fix a bug of the improved pasting HTML contents contents into the editor - -## 9.0.0-dev-9 - -* Improves the new logic of pasting HTML contents into the Editor -* Update `README.md` and the doc -* Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` -* Upgrade the font family button to material 3 -* Rework the font family and font size functionalities to change the font once and type all over the editor - -## 9.0.0-dev-8 - -* Better support for pasting HTML contents from external websites to the editor -* The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) - -## 9.0.0-dev-7 - -* Fix a bug in chaning the background/font color of ol/ul list -* Flutter Quill Extensions: - * Fix link bug in the video url - * Fix patterns - -## 9.0.0-dev-6 - -* Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly -* Bug fixes -* Add the ability to change the background and font color of the ol/ul elements dots and numbers -* Flutter Quill Extensions: - * **Breaking Change**: The `imageProviderBuilder`is now providing the context and image url - -## 9.0.0-dev-5 - -* The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard -* Flutter Quill Extensions: - * Improve the camera button - -## 9.0.0-dev-4 - -* The options parameter in all of the buttons is no longer required which can be useful to create custom toolbar with minimal efforts -* Toolbar buttons fixes in both `flutter_quill` and `flutter_quill_extensions` -* The `QuillProvider` has been dropped and no longer used, the providers will be used only internally from now on and we will not using them as much as possible - -## 9.0.0-dev-3 - -* Breaking Changes: - * Rename `QuillToolbar` to `QuillSimpleToolbar` - * Rename `QuillBaseToolbar` to `QuillToolbar` - * Replace `pasteboard` with `rich_cliboard` -* Fix a bug in the example when inserting an image from url -* Flutter Quill Extensions: - * Add support for copying the image to the system cliboard - -## 9.0.0-dev-2 - -* An attemp to fix CI automated publishing - -## 9.0.0-dev-1 - -* An attemp to fix CI automated publishing - -## 9.0.0-dev - -* **Major Breaking change**: The `QuillProvider` is now optional, the `controller` parameter has been moved to the `QuillEditor` and `QuillToolbar` once again. -* Flutter Quill Extensions; - * **Breaking Change**: Completly change the way how the source code structured to more basic and simple way, organize folders and file names, if you use the library -from `flutter_quill_extensions.dart` then there is nothing you need to do, but if you are using any other import then you need to re-imports -embed, this won't affect how quill js work - * Improvemenets to the image embed - * Add support for `margin` for web - * Add untranslated strings to the `quill_en.arb` - -## 8.6.4 - -* The default value of `keyboardAppearance` for the iOS will be the one from the App/System theme mode instead of always using the `Brightness.light` -* Fix typos in `README.md` - -## 8.6.3 - -* Update the minimum flutter version to `3.16.0` - -## 8.6.2 - -* Restore use of alternative QuillToolbarLinkStyleButton2 widget - -## 8.6.1 - -* Temporary revert style bug fix - -## 8.6.0 - -* **Breaking Change** Support [Flutter 3.16](https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1), please upgrade to the latest stable version of flutter to use this update -* **Breaking Change**: Remove Deprecated Fields -* **Breaking Change**: Extract the shared things between `QuillToolbarConfigurations` and `QuillBaseToolbarConfigurations` -* **Breaking Change**: You no longer need to use `QuillToolbarProvider` when using custom toolbar buttons, the example has been updated -* Bug fixes - -## 8.5.5 - -* Now when opening dialogs by `QuillToolbar` you will not get an exception when you don't use `FlutterQuillLocalizations.delegate` in your `WidgetsApp`, `MaterialApp`, or `CupertinoApp`. The fix is for the `QuillToolbarSearchButton`, `QuillToolbarLinkStyleButton`, and `QuillToolbarColorButton` buttons - -## 8.5.4 - -* The `mobileWidth`, `mobileHeight`, `mobileMargin`, and `mobileAlignment` is now deprecated in `flutter_quill`, they are now defined in `flutter_quill_extensions` -* Deprecate `replaceStyleStringWithSize` function which is in `string.dart` -* Deprecate `alignment`, and `margin` as they don't conform to official Quill JS - -## 8.5.3 - -* Update doc -* Update `README.md` and `CHANGELOG.md` -* Fix typos -* Use `immutable` when possible -* Update `.pubignore` - -## 8.5.2 - -* Updated `README.md`. -* Feature: Added the ability to include a custom callback when the `QuillToolbarColorButton` is pressed. -* The `QuillToolbar` now implements `PreferredSizeWidget`, enabling usage in the AppBar, similar to `QuillBaseToolbar`. - -## 8.5.1 - -* Updated `README.md`. - -## 8.5.0 - -* Migrated to `flutter_localizations` for translations. -* Fixed: Translated all previously untranslated localizations. -* Fixed: Added translations for missing items. -* Fixed: Introduced default Chinese fallback translation. -* Removed: Unused parameters `items` in `QuillToolbarFontFamilyButtonOptions` and `QuillToolbarFontSizeButtonOptions`. -* Updated: Documentation. - -## 8.4.4 - -* Updated `.pubignore` to ignore unnecessary files and folders. - -## 8.4.3 - -* Updated `CHANGELOG.md`. - -## 8.4.2 - -* **Breaking change**: Configuration for `QuillRawEditor` has been moved to a separate class. Additionally, `readOnly` has been renamed to `isReadOnly`. If using `QuillEditor`, no action is required. -* Introduced the ability for developers to override `TextInputAction` in both `QuillRawEditor` and `QuillEditor`. -* Enabled using `QuillRawEditor` without `QuillEditorProvider`. -* Bug fixes. -* Added image cropping implementation in the example. - -## 8.4.1 - -* Added `copyWith` in `OptionalSize` class. - -## 8.4.0 - -* **Breaking change**: Updated `QuillCustomButton` to use `QuillCustomButtonOptions`. Moved all properties from `QuillCustomButton` to `QuillCustomButtonOptions`, replacing `iconData` with `icon` widget for increased customization. -* **Breaking change**: `customButtons` in `QuillToolbarConfigurations` is now of type `List`. -* Bug fixes following the `8.0.0` update. -* Updated `README.md`. -* Improved platform checking. - -## 8.3.0 - -* Added `iconButtonFactor` property to `QuillToolbarBaseButtonOptions` for customizing button size relative to its icon size (defaults to `kIconButtonFactor`, consistent with previous releases). - -## 8.2.6 - -* Organized `QuillRawEditor` code. - -## 8.2.5 - -* Added `builder` property in `QuillEditorConfigurations`. - -## 8.2.4 - -* Adhered to Flutter best practices. -* Fixed auto-focus bug. - -## 8.2.3 - -* Updated `README.md`. - -## 8.2.2 - -* Moved `flutter_quill_test` to a separate package: [flutter_quill_test](https://pub.dev/packages/flutter_quill_test). - -## 8.2.1 - -* Updated `README.md`. - -## 8.2.0 - -* Added the option to add configurations for `flutter_quill_extensions` using `extraConfigurations`. - -## 8.1.11 - -* Followed Dart best practices by using `lints` and removed `pedantic` and `platform` since they are not used. -* Fixed text direction bug. -* Updated `README.md`. - -## 8.1.10 - -* Secret for automated publishing to pub.dev. - -## 8.1.9 - -* Fixed automated publishing to pub.dev. - -## 8.1.8 - -* Fixed automated publishing to pub.dev. - -## 8.1.7 - -* Automated publishing to pub.dev. - -## 8.1.6 - -* Fixed compatibility with `integration_test` by downgrading the minimum version of the platform package to 3.1.0. - -## 8.1.5 - -* Reversed background/font color toolbar button icons. - -## 8.1.4 - -* Reversed background/font color toolbar button tooltips. - -## 8.1.3 - -* Moved images to screenshots instead of `README.md`. - -## 8.1.2 - -* Fixed a bug related to the regexp of the insert link dialog. -* Required Dart 3 as the minimum version. -* Code cleanup. -* Added a spacer widget between each button in the `QuillToolbar`. - -## 8.1.1 - -* Fixed null error in line.dart #1487(https://github.com/singerdmx/flutter*quill/issues/1487). - -## 8.1.0 - -* Fixed a word typo of `mirgration` to `migration` in the readme & migration document. -* Updated migration guide. -* Removed property `enableUnfocusOnTapOutside` in `QuillEditor` configurations and added `isOnTapOutsideEnabled` instead. -* Added a new callback called `onTapOutside` in the `QuillEditorConfigurations` to perform actions when tapping outside the editor. -* Fixed a bug that caused the web platform to not unfocus the editor when tapping outside of it. To override this, please pass a value to the `onTapOutside` callback. -* Removed the old property of `iconTheme`. Instead, pass `iconTheme` in the button options; you will find the `base` property inside it with `iconTheme`. - -## 8.0.0 - -* If you have migrated recently, don't be alarmed by this update; it adds documentation, a migration guide, and marks the version as a more stable release. Although there are breaking changes (as reported by some developers), the major version was not changed due to time constraints during development. A single property was also renamed from `code` to `codeBlock` in the `elements` of the new `QuillEditorConfigurations` class. -* Updated the README for better readability. - -## 7.10.2 - -* Removed line numbers from code blocks by default. You can still enable this feature thanks to the new configurations in the `QuillEditor`. Find the `elementOptions` property and enable `enableLineNumbers`. - -## 7.10.1 - -* Fixed issues and utilized the new parameters. -* No longer need to use `MaterialApp` for most toolbar button child builders. -* Compatibility with [fresh_quill_extensions](https://pub.dev/packages/fresh_quill_extensions), a temporary alternative to [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions). -* Updated most of the documentation in `README.md`. - -## 7.10.0 - -* **Breaking change**: `QuillToolbar.basic()` can be accessed directly from `QuillToolbar()`, and the old `QuillToolbar` can be accessed from `QuillBaseToolbar`. -* Refactored Quill editor and toolbar configurations into a single class each. -* After changing checkbox list values, the controller will not request keyboard focus by default. -* Moved toolbar and editor configurations directly into the widget but still use inherited widgets internally. -* Fixes to some code after the refactoring. - -## 7.9.0 - -* Buttons Improvemenets -* Refactor all the button configurations that used in `QuillToolbar.basic()` but there are still few lefts -* **Breaking change**: Remove some configurations from the QuillToolbar and move them to the new `QuillProvider`, please notice this is a development version and this might be changed in the next few days, the stable release will be ready in less than 3 weeks -* Update `flutter_quill_extensions` and it will be published into pub.dev soon. -* Allow you to customize the search dialog by custom callback with child builder - -## 7.8.0 - -* **Important note**: this is not test release yet, it works but need more test and changes and breaking changes, we don't have development version and it will help us if you try the latest version and report the issues in Github but if you want a stable version please use `7.4.16`. this refactoring process will not take long and should be done less than three weeks with the testing. -* We managed to refactor most of the buttons configurations and customizations in the `QuillProvider`, only three lefts then will start on refactoring the toolbar configurations -* Code improvemenets - -## 7.7.0 - -* **Breaking change**: We have mirgrated more buttons in the toolbar configurations, you can do change them in the `QuillProvider` -* Important bug fixes - -## 7.6.1 - -* Bug fixes - -## 7.6.0 - -* **Breaking change**: To customize the buttons in the toolbar, you can do that in the `QuillProvider` - -## 7.5.0 - -* **Breaking change**: The widgets `QuillEditor` and `QuillToolbar` are no longer have controller parameter, instead you need to make sure in the widget tree you have wrapped them with `QuillProvider` widget and provide the controller and the require configurations - -## 7.4.16 - -* Update documentation and README.md - -## 7.4.15 - -* Custom style attrbuites for platforms other than mobile (alignment, margin, width, height) -* Bug fixes and other improvemenets - -## 7.4.14 - -* Improve performance by reducing the number of widgets rebuilt by listening to media query for only the needed things, for example instead of using `MediaQuery.of(context).size`, now we are using `MediaQuery.sizeOf(context)` -* Add MediaButton for picking the images only since the video one is not ready -* A new feature which allows customizing the text selection in quill editor which is useful for custom theme design system for custom app widget - -## 7.4.13 - -* Fixed tab editing when in readOnly mode. - -## 7.4.12 - -* Update the minimum version of device_info_plus to 9.1.0. - -## 7.4.11 - -* Add sw locale. - -## 7.4.10 - -* Update translations. - -## 7.4.9 - -* Style recognition fixes. - -## 7.4.8 - -* Upgrade dependencies. - -## 7.4.7 - -* Add Vietnamese and German translations. - -## 7.4.6 - -* Fix more null errors in Leaf.retain [##1394](https://github.com/singerdmx/flutter-quill/issues/1394) and Line.delete [##1395](https://github.com/singerdmx/flutter-quill/issues/1395). - -## 7.4.5 - -* Fix null error in Container.insert [##1392](https://github.com/singerdmx/flutter-quill/issues/1392). - -## 7.4.4 - -* Fix extra padding on checklists [##1131](https://github.com/singerdmx/flutter-quill/issues/1131). - -## 7.4.3 - -* Fixed a space input error on iPad. - -## 7.4.2 - -* Fix bug with keepStyleOnNewLine for link. - -## 7.4.1 - -* Fix toolbar dividers condition. - -## 7.4.0 - -* Support Flutter version 3.13.0. - -## 7.3.3 - -* Updated Dependencies conflicting. - -## 7.3.2 - -* Added builder for custom button in _LinkDialog. - -## 7.3.1 - -* Added case sensitive and whole word search parameters. -* Added wrap around. -* Moved search dialog to the bottom in order not to override the editor and the text found. -* Other minor search dialog enhancements. - -## 7.3.0 - -* Add default attributes to basic factory. - -## 7.2.19 - -* Feat/link regexp. - -## 7.2.18 - -* Fix paste block text in words apply same style. - -## 7.2.17 - -* Fix paste text mess up style. -* Add support copy/cut block text. - -## 7.2.16 - -* Allow for custom context menu. - -## 7.2.15 - -* Add flutter_quill.delta library which only exposes Delta datatype. - -## 7.2.14 - -* Fix errors when the editor is used in the `screenshot` package. - -## 7.2.13 - -* Fix around image can't delete line break. - -## 7.2.12 - -* Add support for copy/cut select image and text together. - -## 7.2.11 - -* Add affinity for localPosition. - -## 7.2.10 - -* LINE._getPlainText queryChild inclusive=false. - -## 7.2.9 - -* Add toPlainText method to `EmbedBuilder`. - -## 7.2.8 - -* Add custom button widget in toolbar. - -## 7.2.7 - -* Fix language code of Japan. - -## 7.2.6 - -* Style custom toolbar buttons like builtins. - -## 7.2.5 - -* Always use text cursor for editor on desktop. - -## 7.2.4 - -* Fixed keepStyleOnNewLine. - -## 7.2.3 - -* Get pixel ratio from view. - -## 7.2.2 - -* Prevent operations on stale editor state. - -## 7.2.1 - -* Add support for android keyboard content insertion. -* Enhance color picker, enter hex color and color palette option. - -## 7.2.0 - -* Checkboxes, bullet points, and number points are now scaled based on the default paragraph font size. - -## 7.1.20 - -* Pass linestyle to embedded block. - -## 7.1.19 - -* Fix Rtl leading alignment problem. - -## 7.1.18 - -* Support flutter latest version. - -## 7.1.17+1 - -* Updates `device_info_plus` to version 9.0.0 to benefit from AGP 8 (see [changelog##900](https://pub.dev/packages/device_info_plus/changelog##900)). - -## 7.1.16 - -* Fixed subscript key from 'sup' to 'sub'. - -## 7.1.15 - -* Fixed a bug introduced in 7.1.7 where each section in `QuillToolbar` was displayed on its own line. - -## 7.1.14 - -* Add indents change for multiline selection. - -## 7.1.13 - -* Add custom recognizer. - -## 7.1.12 - -* Add superscript and subscript styles. - -## 7.1.11 - -* Add inserting indents for lines of list if text is selected. - -## 7.1.10 - -* Image embedding tweaks - * Add MediaButton which is intened to superseed the ImageButton and VideoButton. Only image selection is working. - * Implement image insert for web (image as base64) - -## 7.1.9 - -* Editor tweaks PR from bambinoua(https://github.com/bambinoua). - * Shortcuts now working in Mac OS - * QuillDialogTheme is extended with new properties buttonStyle, linkDialogConstraints, imageDialogConstraints, isWrappable, runSpacing, - * Added LinkStyleButton2 with new LinkStyleDialog (similar to Quill implementation - * Conditinally use Row or Wrap for dialog's children. - * Update minimum Dart SDK version to 2.17.0 to use enum extensions. - * Use merging shortcuts and actions correclty (if the key combination is the same) - -## 7.1.8 - -* Dropdown tweaks - * Add itemHeight, itemPadding, defaultItemColor for customization of dropdown items. - * Remove alignment property as useless. - * Fix bugs with max width when width property is null. - -## 7.1.7 - -* Toolbar tweaks. - * Implement tooltips for embed CameraButton, VideoButton, FormulaButton, ImageButton. - * Extends customization for SelectAlignmentButton, QuillFontFamilyButton, QuillFontSizeButton adding padding, text style, alignment, width. - * Add renderFontFamilies to QuillFontFamilyButton to show font faces in dropdown. - * Add AxisDivider and its named constructors for for use in parent project. - * Export ToolbarButtons enum to allow specify tooltips for SelectAlignmentButton. - * Export QuillFontFamilyButton, SearchButton as they were not exported before. - * Deprecate items property in QuillFontFamilyButton, QuillFontSizeButton as the it can be built usinr rawItemsMap. - * Make onSelection QuillFontFamilyButton, QuillFontSizeButton omittable as no need to execute callback outside if controller is passed to widget. - -Now the package is more friendly for web projects. - -## 7.1.6 - -* Add enableUnfocusOnTapOutside field to RawEditor and Editor widgets. - -## 7.1.5 - -* Add tooltips for toolbar buttons. - -## 7.1.4 - -* Fix inserting tab character in lists. - -## 7.1.3 - -* Fix ios cursor bug when word.length==1. - -## 7.1.2 - -* Fix non scrollable editor exception, when tapped under content. - -## 7.1.1 - -* customLinkPrefixes parameter * makes possible to open links with custom protoco. - -## 7.1.0 - -* Fix ordered list numeration with several lists in document. - -## 7.0.9 - -* Use const constructor for EmbedBuilder. - -## 7.0.8 - -* Fix IME position bug with scroller. - -## 7.0.7 - -* Add TextFieldTapRegion for contextMenu. - -## 7.0.6 - -* Fix line style loss on new line from non string. - -## 7.0.5 - -* Fix IME position bug for Mac and Windows. -* Unfocus when tap outside editor. fix the bug that cant refocus in afterButtonPressed after click ToggleStyleButton on Mac. - -## 7.0.4 - -* Have text selection span full line height for uneven sized text. - -## 7.0.3 - -* Fix ordered list numeration for lists with more than one level of list. - -## 7.0.2 - -* Allow widgets to override widget span properties. - -## 7.0.1 - -* Update i18n_extension dependency to version 8.0.0. - -## 7.0.0 - -* Breaking change: Tuples are no longer used. They have been replaced with a number of data classes. - -## 6.4.4 - -* Increased compatibility with Flutter widget tests. - -## 6.4.3 - -* Update dependencies (collection: 1.17.0, flutter_keyboard_visibility: 5.4.0, quiver: 3.2.1, tuple: 2.0.1, url_launcher: 6.1.9, characters: 1.2.1, i18n_extension: 7.0.0, device_info_plus: 8.1.0) - -## 6.4.2 - -* Replace `buildToolbar` with `contextMenuBuilder`. - -## 6.4.1 - -* Control the detect word boundary behaviour. - -## 6.4.0 - -* Use `axis` to make the toolbar vertical. -* Use `toolbarIconCrossAlignment` to align the toolbar icons on the cross axis. -* Breaking change: `QuillToolbar`'s parameter `toolbarHeight` was renamed to `toolbarSize`. - -## 6.3.5 - -* Ability to add custom shortcuts. - -## 6.3.4 - -* Update clipboard status prior to showing selected text overlay. - -## 6.3.3 - -* Fixed handling of mac intents. - -## 6.3.2 - -* Added `unknownEmbedBuilder` to QuillEditor. -* Fix error style when input chinese japanese or korean. - -## 6.3.1 - -* Add color property to the basic factory function. - -## 6.3.0 - -* Support Flutter 3.7. - -## 6.2.2 - -* Fix: nextLine getter null where no assertion. - -## 6.2.1 - -* Revert "Align numerical and bullet lists along with text content". - -## 6.2.0 - -* Align numerical and bullet lists along with text content. - -## 6.1.12 - -* Apply i18n for default font dropdown option labels corresponding to 'Clear'. - -## 6.1.11 - -* Remove iOS hack for delaying focus calculation. - -## 6.1.10 - -* Delay focus calculation for iOS. - -## 6.1.9 - -* Bump keyboard show up wait to 1 sec. - -## 6.1.8 - -* Recalculate focus when showing keyboard. - -## 6.1.7 - -* Add czech localizations. - -## 6.1.6 - -* Upgrade i18n_extension to 6.0.0. - -## 6.1.5 - -* Fix formatting exception. - -## 6.1.4 - -* Add double quotes validation. - -## 6.1.3 - -* Revert "fix order list numbering (##988)". - -## 6.1.2 - -* Add typing shortcuts. - -## 6.1.1 - -* Fix order list numbering. - -## 6.1.0 - -* Add keyboard shortcuts for editor actions. - -## 6.0.10 - -* Upgrade device info plus to ^7.0.0. - -## 6.0.9 - -* Don't throw showAutocorrectionPromptRect not implemented. The function is called with every keystroke as a user is typing. - -## 6.0.8+1 - -* Fixes null pointer when setting documents. - -## 6.0.8 - -* Make QuillController.document mutable. - -## 6.0.7 - -* Allow disabling of selection toolbar. - -## 6.0.6+1 - -* Revert 6.0.6. - -## 6.0.6 - -* Fix wrong custom embed key. - -## 6.0.5 - -* Fixes toolbar buttons stealing focus from editor. - -## 6.0.4 - -* Bug fix for Type 'Uint8List' not found. - -## 6.0.3 - -* Add ability to paste images. - -## 6.0.2 - -* Address Dart Analysis issues. - -## 6.0.1 - -* Changed translation country code (zh_HK -> zh_hk) to lower case, which is required for i18n_extension used in flutter_quill. -* Add localization in example's main to demonstrate translation. -* Issue Windows selection's copy / paste tool bar not shown ##861: add selection's copy / paste toolbar, escape to hide toolbar, mouse right click to show toolbar, ctrl-Y / ctrl-Z to undo / redo. -* Image and video displayed in Windows platform caused screen flickering while selecting text, a sample_data_nomedia.json asset is added for Desktop to demonstrate the added features. -* Known issue: keyboard action sometimes causes exception mentioned in Flutter's issue ##106475 (Windows Keyboard shortcuts stop working after modifier key repeat flutter/flutter##106475). -* Know issue: user needs to click the editor to get focus before toolbar is able to display. - -## 6.0.0 BREAKING CHANGE - -* Removed embed (image, video & formula) blocks from the package to reduce app size. - -These blocks have been moved to the package `flutter_quill_extensions`, migrate by filling the `embedBuilders` and `embedButtons` parameters as follows: - -``` -import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; - -QuillEditor.basic( - controller: controller, - embedBuilders: FlutterQuillEmbeds.builders(), -); - -QuillToolbar.basic( - controller: controller, - embedButtons: FlutterQuillEmbeds.buttons(), -); -``` - -## 5.4.2 - -* Upgrade i18n_extension. - -## 5.4.1 - -* Update German Translation. - -## 5.4.0 - -* Added Formula Button (for maths support). - -## 5.3.2 - -* Add more font family. - -## 5.3.1 - -* Enable search when text is not empty. - -## 5.3.0 - -* Added search function. - -## 5.2.11 - -* Remove default small color. - -## 5.2.10 - -* Don't wrap the QuillEditor's child in the EditorTextSelectionGestureDetector if selection is disabled. - -## 5.2.9 - -* Added option to modify SelectHeaderStyleButton options. -* Added option to click again on h1, h2, h3 button to go back to normal. - -## 5.2.8 - -* Remove tooltip for LinkStyleButton. -* Make link match regex case insensitive. - -## 5.2.7 - -* Add locale to QuillEditor.basic. - -## 5.2.6 - -* Fix keyboard pops up when resizing the image. - -## 5.2.5 - -* Upgrade youtube_player_flutter_quill to 8.2.2. - -## 5.2.4 - -* Upgrade youtube_player_flutter_quill to 8.2.1. - -## 5.2.3 - -* Flutter Quill Doesn't Work On iOS 16 or Xcode 14 Betas (Stored properties cannot be marked potentially unavailable with '@available'). - -## 5.2.2 - -* Fix Web Unsupported operation: Platform.\_operatingSystem error. - -## 5.2.1 - -* Rename QuillCustomIcon to QuillCustomButton. - -## 5.2.0 - -* Support font family selection. - -## 5.1.1 - -* Update README. - -## 5.1.0 - -* Added CustomBlockEmbed and customElementsEmbedBuilder. - -## 5.0.5 - -* Upgrade device_info_plus to 4.0.0. - -## 5.0.4 - -* Added onVideoInit callback for video documents. - -## 5.0.3 - -* Update dependencies. - -## 5.0.2 - -* Keep cursor position on checkbox tap. - -## 5.0.1 - -* Fix static analysis errors. - -## 5.0.0 - -* Flutter 3.0.0 support. - -## 4.2.3 - -* Ignore color:inherit and convert double to int for level. - -## 4.2.2 - -* Add clear option to font size dropdown. - -## 4.2.1 - -* Refactor font size dropdown. - -## 4.2.0 - -* Ensure selectionOverlay is available for showToolbar. - -## 4.1.9 - -* Using properly iconTheme colors. - -## 4.1.8 - -* Update font size dropdown. - -## 4.1.7 - -* Convert FontSize to a Map to allow for named Font Size. - -## 4.1.6 - -* Update quill_dropdown_button.dart. - -## 4.1.5 - -* Add Font Size dropdown to the toolbar. - -## 4.1.4 - -* New borderRadius for iconTheme. - -## 4.1.3 - -* Fix selection handles show/hide after paste, backspace, copy. - -## 4.1.2 - -* Add full support for hardware keyboards (Chromebook, Android tablets, etc) that don't alter screen UI. - -## 4.1.1 - -* Added textSelectionControls field in QuillEditor. - -## 4.1.0 - -* Added Node to linkActionPickerDelegate. - -## 4.0.12 - -* Add Persian(fa) language. - -## 4.0.11 - -* Fix cut selection error in multi-node line. - -## 4.0.10 - -* Fix vertical caret position bug. - -## 4.0.9 - -* Request keyboard focus when no child is found. - -## 4.0.8 - -* Fix blank lines do not display when **web*renderer=html. - -## 4.0.7 - -* Refactor getPlainText (better handling of blank lines and lines with multiple markups. - -## 4.0.6 - -* Bug fix for copying text with new lines. - -## 4.0.5 - -* Fixed casting null to Tuple2 when link dialog is dismissed without any input (e.g. barrier dismissed). - -## 4.0.4 - -* Bug fix for text direction rtl. - -## 4.0.3 - -* Support text direction rtl. - -## 4.0.2 - -* Clear toggled style on selection change. - -## 4.0.1 - -* Fix copy/cut/paste/selectAll not working. - -## 4.0.0 - -* Upgrade for Flutter 2.10. - -## 3.9.11 - -* Added Indonesian translation. - -## 3.9.10 - -* Fix for undoing a modification ending with an indented line. - -## 3.9.9 - -* iOS: Save image whose filename does not end with image file extension. - -## 3.9.8 - -* Added Urdu translation. - -## 3.9.7 - -* Fix for clicking on the Link button without any text on a new line crashes. - -## 3.9.6 - -* Apply locale to QuillEditor(contents). - -## 3.9.5 - -* Fix image pasting. - -## 3.9.4 - -* Hiding dialog after selecting action for image. - -## 3.9.3 - -* Update ImageResizer for Android. - -## 3.9.2 - -* Copy image with its style. - -## 3.9.1 - -* Support resizing image. - -## 3.9.0 - -* Image menu options for copy/remove. - -## 3.8.8 - -* Update set textEditingValue. - -## 3.8.7 - -* Fix checkbox not toggled correctly in toolbar button. - -## 3.8.6 - -* Fix cursor position changes when checking/unchecking the checkbox. - -## 3.8.5 - -* Fix \_handleDragUpdate in \_TextSelectionHandleOverlayState. - -## 3.8.4 - -* Fix link dialog layout. - -## 3.8.3 - -* Fix for errors on a non scrollable editor. - -## 3.8.2 - -* Fix certain keys not working on web when editor is a child of a scroll view. - -## 3.8.1 - -* Refactor \_QuillEditorState to QuillEditorState. - -## 3.8.0 - -* Support pasting with format. - -## 3.7.3 - -* Fix selection overlay for collapsed selection. - -## 3.7.2 - -* Reverted Embed toPlainText change. - -## 3.7.1 - -* Change Embed toPlainText to be empty string. - -## 3.7.0 - -* Replace Toolbar showHistory group with individual showRedo and showUndo. - -## 3.6.5 - -* Update Link dialogue for image/video. - -## 3.6.4 - -* Link dialogue TextInputType.multiline. - -## 3.6.3 - -* Bug fix for link button text selection. - -## 3.6.2 - -* Improve link button. - -## 3.6.1 - -* Remove SnackBar 'What is entered is not a link'. - -## 3.6.0 - -* Allow link button to enter text. - -## 3.5.3 - -* Change link button behavior. - -## 3.5.2 - -* Bug fix for embed. - -## 3.5.1 - -* Bug fix for platform util. - -## 3.5.0 - -* Removed redundant classes. - -## 3.4.4 - -* Add more translations. - -## 3.4.3 - -* Preset link from attributes. - -## 3.4.2 - -* Fix launch link edit mode. - -## 3.4.1 - -* Placeholder effective in scrollable. - -## 3.4.0 - -* Option to save image in read-only mode. - -## 3.3.1 - -* Pass any specified key in QuillEditor constructor to super. - -## 3.3.0 - -* Fixed Style toggle issue. - -## 3.2.1 - -* Added new translations. - -## 3.2.0 - -* Support multiple links insertion on the go. - -## 3.1.1 - -* Add selection completed callback. - -## 3.1.0 - -* Fixed image ontap functionality. - -## 3.0.4 - -* Add maxContentWidth constraint to editor. - -## 3.0.3 - -* Do not show caret on screen when the editor is not focused. - -## 3.0.2 - -* Fix launch link for read-only mode. - -## 3.0.1 - -* Handle null value of Attribute.link. - -## 3.0.0 - -* Launch link improvements. -* Removed QuillSimpleViewer. - -## 2.5.2 - -* Skip image when pasting. - -## 2.5.1 - -* Bug fix for Desktop `Shift` + `Click` support. - -## 2.5.0 - -* Update checkbox list. - -## 2.4.1 - -* Desktop selection improvements. - -## 2.4.0 - -* Improve inline code style. - -## 2.3.3 - -* Improves selection rects to have consistent height regardless of individual segment text styles. - -## 2.3.2 - -* Allow disabling floating cursor. - -## 2.3.1 - -* Preserve last newline character on delete. - -## 2.3.0 - -* Massive changes to support flutter 2.8. - -## 2.2.2 - -* iOS - floating cursor. - -## 2.2.1 - -* Bug fix for imports supporting flutter 2.8. - -## 2.2.0 - -* Support flutter 2.8. - -## 2.1.1 - -* Add methods of clearing editor and moving cursor. - -## 2.1.0 - -* Add delete handler. - -## 2.0.23 - -* Support custom replaceText handler. - -## 2.0.22 - -* Fix attribute compare and fix font size parsing. - -## 2.0.21 - -* Handle click on embed object. - -## 2.0.20 - -* Improved UX/UI of Image widget. - -## 2.0.19 - -* When uploading a video, applying indicator. - -## 2.0.18 - -* Make toolbar dividers optional. - -## 2.0.17 - -* Allow alignment of the toolbar icons to match WrapAlignment. - -## 2.0.16 - -* Add hide / show alignment buttons. - -## 2.0.15 - -* Implement change cursor to SystemMouseCursors.click when hovering a link styled text. - -## 2.0.14 - -* Enable customize the checkbox widget using DefaultListBlockStyle style. - -## 2.0.13 - -* Improve the scrolling performance by reducing the repaint areas. - -## 2.0.12 - -* Fix the selection effect can't be seen as the textLine with background color. - -## 2.0.11 - -* Fix visibility of text selection handlers on scroll. - -## 2.0.10 - -* cursorConnt.color notify the text_line to repaint if it was disposed. - -## 2.0.9 - -* Improve UX when trying to add a link. - -## 2.0.8 - -* Adding translations to the toolbar. - -## 2.0.7 - -* Added theming options for toolbar icons and LinkDialog. - -## 2.0.6 - -* Avoid runtime error when placed inside TabBarView. - -## 2.0.5 - -* Support inline code formatting. - -## 2.0.4 - -* Enable history shortcuts for desktop. - -## 2.0.3 - -* Fix cursor when line contains image. - -## 2.0.2 - -* Address KeyboardListener class name conflict. - -## 2.0.1 - -* Upgrade flutter_colorpicker to 0.5.0. - -## 2.0.0 - -* Text Alignment functions + Block Format standards. - -## 1.9.6 - -* Support putting QuillEditor inside a Scrollable view. - -## 1.9.5 - -* Skip image when pasting. - -## 1.9.4 - -* Bug fix for cursor position when tapping at the end of line with image(s). - -## 1.9.3 - -* Bug fix when line only contains one image. - -## 1.9.2 - -* Support for building custom inline styles. - -## 1.9.1 - -* Cursor jumps to the most appropriate offset to display selection. - -## 1.9.0 - -* Support inline image. - -## 1.8.3 - -* Updated quill_delta. - -## 1.8.2 - -* Support mobile image alignment. - -## 1.8.1 - -* Support mobile custom size image. - -## 1.8.0 - -* Support entering link for image/video. - -## 1.7.3 - -* Bumps photo_view version. - -## 1.7.2 - -* Fix static analysis error. - -## 1.7.1 - -* Support Youtube video. - -## 1.7.0 - -* Support video. - -## 1.6.4 - -* Bug fix for clear format button. - -## 1.6.3 - -* Fixed dragging right handle scrolling issue. - -## 1.6.2 - -* Fixed the position of the selection status drag handle. - -## 1.6.1 - -* Upgrade image_picker and flutter_colorpicker. - -## 1.6.0 - -* Support Multi Row Toolbar. - -## 1.5.0 - -* Remove file_picker dependency. - -## 1.4.1 - -* Remove filesystem_picker dependency. - -## 1.4.0 - -* Remove path_provider dependency. - -## 1.3.4 - -* Add option to paintCursorAboveText. - -## 1.3.3 - -* Upgrade file_picker version. - -## 1.3.2 - -* Fix copy/paste bug. - -## 1.3.1 - -* New logo. - -## 1.3.0 - -* Support flutter 2.2.0. - -## 1.2.2 - -* Checkbox supports tapping. - -## 1.2.1 - -* Indented position not holding while editing. - -## 1.2.0 - -* Fix image button cancel causes crash. - -## 1.1.8 - -* Fix height of empty line bug. - -## 1.1.7 - -* Fix text selection in read-only mode. - -## 1.1.6 - -* Remove universal_html dependency. - -## 1.1.5 - -* Enable "Select", "Select All" and "Copy" in read-only mode. - -## 1.1.4 - -* Fix text selection issue. - -## 1.1.3 - -* Update example folder. - -## 1.1.2 - -* Add pedantic. - -## 1.1.1 - -* Base64 image support. - -## 1.1.0 - -* Support null safety. - -## 1.0.9 - -* Web support for raw editor and keyboard listener. - -## 1.0.8 - -* Support token attribute. - -## 1.0.7 - -* Fix crash on web (dart:io). - -## 1.0.6 - -* Add desktop support WINDOWS, MACOS and LINUX. - -## 1.0.5 - -* Bug fix: Can not insert newline when Bold is toggled ON. - -## 1.0.4 - -* Upgrade photo_view to ^0.11.0. - -## 1.0.3 - -* Fix issue that text is not displayed while typing WEB. - -## 1.0.2 - -* Update toolbar in sample home page. - -## 1.0.1 - -* Fix static analysis errors. - -## 1.0.0 - -* Support flutter 2.0. - -## 1.0.0-dev.2 - -* Improve link handling for tel, mailto and etc. - -## 1.0.0-dev.1 - -* Upgrade prerelease SDK & Bump for master. - -## 0.3.5 - -* Fix for cursor focus issues when keyboard is on. - -## 0.3.4 - -* Improve link handling for tel, mailto and etc. - -## 0.3.3 - -* More fix on cursor focus issue when keyboard is on. - -## 0.3.2 - -* Fix cursor focus issue when keyboard is on. - -## 0.3.1 - -* cursor focus when keyboard is on. - -## 0.3.0 - -* Line Height calculated based on font size. - -## 0.2.12 - -* Support placeholder. - -## 0.2.11 - -* Fix static analysis error. - -## 0.2.10 - -* Update TextInputConfiguration autocorrect to true in stable branch. - -## 0.2.9 - -* Update TextInputConfiguration autocorrect to true. - -## 0.2.8 - -* Support display local image besides network image in stable branch. - -## 0.2.7 - -* Support display local image besides network image. - -## 0.2.6 - -* Fix cursor after pasting. - -## 0.2.5 - -* Toggle text/background color button in toolbar. - -## 0.2.4 - -* Support the use of custom icon size in toolbar. - -## 0.2.3 - -* Support custom styles and image on local device storage without uploading. - -## 0.2.2 - -* Update git repo. - -## 0.2.1 - -* Fix static analysis error. - -## 0.2.0 - -* Add checked/unchecked list button in toolbar. - -## 0.1.8 - -* Support font and size attributes. - -## 0.1.7 - -* Support checked/unchecked list. - -## 0.1.6 - -* Fix getExtentEndpointForSelection. - -## 0.1.5 - -* Support text alignment. - -## 0.1.4 - -* Handle url with trailing spaces. - -## 0.1.3 - -* Handle cursor position change when undo/redo. - -## 0.1.2 - -* Handle more text colors. - -## 0.1.1 - -* Fix cursor issue when undo. - -## 0.1.0 - -* Fix insert image. - -## 0.0.9 - -* Handle rgba color. - -## 0.0.8 - -* Fix launching url. - -## 0.0.7 - -* Handle multiple image inserts. - -## 0.0.6 - -* More toolbar functionality. - -## 0.0.5 - -* Update example. - -## 0.0.4 - -* Update example. - -## 0.0.3 - -* Update home page meta data. - -## 0.0.2 - -* Support image upload and launch url in read-only mode. - -## 0.0.1 - -* Rich text editor based on Quill Delta. - diff --git a/dart_quill_delta/LICENSE b/dart_quill_delta/LICENSE deleted file mode 100644 index e7ff73e1b..000000000 --- a/dart_quill_delta/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Flutter Quill project and open source contributors. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/dart_quill_delta/README.md b/dart_quill_delta/README.md deleted file mode 100644 index 7d7aad35f..000000000 --- a/dart_quill_delta/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Dart Quill Delta -A port of [quill-js-delta](https://github.com/quilljs/delta/) from typescript to dart \ No newline at end of file diff --git a/dart_quill_delta/analysis_options.yaml b/dart_quill_delta/analysis_options.yaml deleted file mode 100644 index dee8927aa..000000000 --- a/dart_quill_delta/analysis_options.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# This file configures the static analysis results for your project (errors, -# warnings, and lints). -# -# This enables the 'recommended' set of lints from `package:lints`. -# This set helps identify many issues that may lead to problems when running -# or consuming Dart code, and enforces writing Dart using a single, idiomatic -# style and format. -# -# If you want a smaller set of lints you can change this to specify -# 'package:lints/core.yaml'. These are just the most critical lints -# (the recommended set includes the core lints). -# The core lints are also what is used by pub.dev for scoring packages. - -include: package:lints/recommended.yaml - -# Uncomment the following section to specify additional rules. - -# linter: -# rules: -# - camel_case_types - -# analyzer: -# exclude: -# - path/to/excluded/files/** - -# For more information about the core and recommended set of lints, see -# https://dart.dev/go/core-lints - -# For additional information about configuring this file, see -# https://dart.dev/guides/language/analysis-options diff --git a/dart_quill_delta/example/dart_quill_delta_example.dart b/dart_quill_delta/example/dart_quill_delta_example.dart deleted file mode 100644 index ab73b3a23..000000000 --- a/dart_quill_delta/example/dart_quill_delta_example.dart +++ /dev/null @@ -1 +0,0 @@ -void main() {} diff --git a/dart_quill_delta/lib/dart_quill_delta.dart b/dart_quill_delta/lib/dart_quill_delta.dart deleted file mode 100644 index d29a9063a..000000000 --- a/dart_quill_delta/lib/dart_quill_delta.dart +++ /dev/null @@ -1,5 +0,0 @@ -library; - -export './src/delta/delta.dart'; -export './src/delta/delta_iterator.dart'; -export './src/operation/operation.dart'; diff --git a/dart_quill_delta/lib/src/delta/delta.dart b/dart_quill_delta/lib/src/delta/delta.dart deleted file mode 100644 index fc0527bcf..000000000 --- a/dart_quill_delta/lib/src/delta/delta.dart +++ /dev/null @@ -1,563 +0,0 @@ -import 'dart:math' as math; - -import 'package:collection/collection.dart'; -import 'package:diff_match_patch/diff_match_patch.dart' as dmp; -import 'package:quiver/core.dart'; - -import '../operation/operation.dart'; -import 'delta_iterator.dart'; - -/// Delta represents a document or a modification of a document as a sequence of -/// insert, delete and retain operations. -/// -/// Delta consisting of only "insert" operations is usually referred to as -/// "document delta". When delta includes also "retain" or "delete" operations -/// it is a "change delta". -class Delta { - /// Creates new empty [Delta]. - factory Delta() => Delta._([]); - - Delta._(this.operations); - - /// Creates new [Delta] from [other]. - factory Delta.from(Delta other) => - Delta._(List.from(other.operations)); - - /// Creates new [Delta] from a List of Operation - factory Delta.fromOperations(List operations) => - Delta._(operations.toList()); - - // Placeholder char for embed in diff() - static final String _kNullCharacter = String.fromCharCode(0); - - /// Transforms two attribute sets. - static Map? transformAttributes( - Map? a, Map? b, bool priority) { - if (a == null) return b; - if (b == null) return null; - - if (!priority) return b; - - final result = b.keys.fold>({}, (attributes, key) { - if (!a.containsKey(key)) attributes[key] = b[key]; - return attributes; - }); - - return result.isEmpty ? null : result; - } - - /// Composes two attribute sets. - static Map? composeAttributes( - Map? a, Map? b, - {bool keepNull = false}) { - a ??= const {}; - b ??= const {}; - - final result = Map.from(a)..addAll(b); - final keys = result.keys.toList(growable: false); - - if (!keepNull) { - for (final key in keys) { - if (result[key] == null) result.remove(key); - } - } - - return result.isEmpty ? null : result; - } - - ///get anti-attr result base on base - static Map invertAttributes( - Map? attr, Map? base) { - attr ??= const {}; - base ??= const {}; - - final baseInverted = base.keys.fold({}, (dynamic memo, key) { - if (base![key] != attr![key] && attr.containsKey(key)) { - memo[key] = base[key]; - } - return memo; - }); - - final inverted = - Map.from(attr.keys.fold(baseInverted, (memo, key) { - if (base![key] != attr![key] && !base.containsKey(key)) { - memo[key] = null; - } - return memo; - })); - return inverted; - } - - /// Returns diff between two attribute sets - static Map? diffAttributes( - Map? a, Map? b) { - a ??= const {}; - b ??= const {}; - - final attributes = {}; - for (final key in (a.keys.toList()..addAll(b.keys))) { - if (a[key] != b[key]) { - attributes[key] = b.containsKey(key) ? b[key] : null; - } - } - - return attributes.keys.isNotEmpty ? attributes : null; - } - - final List operations; - - int modificationCount = 0; - - /// Creates [Delta] from de-serialized JSON representation. - /// - /// If `dataDecoder` parameter is not null then it is used to additionally - /// decode the operation's data object. Only applied to insert operations. - static Delta fromJson(List data, {DataDecoder? dataDecoder}) { - return Delta._(data - .map((op) => Operation.fromJson(op, dataDecoder: dataDecoder)) - .toList()); - } - - /// Returns list of operations in this delta. - List toList() => List.from(operations); - - /// Returns JSON-serializable version of this delta. - List> toJson() => - toList().map((operation) => operation.toJson()).toList(); - - /// Returns `true` if this delta is empty. - bool get isEmpty => operations.isEmpty; - - /// Returns `true` if this delta is not empty. - bool get isNotEmpty => operations.isNotEmpty; - - /// Returns number of operations in this delta. - int get length => operations.length; - - /// Returns [Operation] at specified [index] in this delta. - Operation operator [](int index) => operations[index]; - - /// Returns [Operation] at specified [index] in this delta. - Operation elementAt(int index) => operations.elementAt(index); - - /// Returns the first [Operation] in this delta. - Operation get first => operations.first; - - /// Returns the last [Operation] in this delta. - Operation get last => operations.last; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - if (other is! Delta) return false; - final typedOther = other; - const comparator = ListEquality(DefaultEquality()); - return comparator.equals(operations, typedOther.operations); - } - - @override - int get hashCode => hashObjects(operations); - - /// Retain [count] of characters from current position. - void retain(int count, [Map? attributes]) { - assert(count >= 0); - if (count == 0) return; // no-op - push(Operation.retain(count, attributes)); - } - - /// Insert [data] at current position. - void insert(dynamic data, [Map? attributes]) { - if (data is String && data.isEmpty) return; // no-op - push(Operation.insert(data, attributes)); - } - - /// Delete [count] characters from current position. - void delete(int count) { - assert(count >= 0); - if (count == 0) return; - push(Operation.delete(count)); - } - - void _mergeWithTail(Operation operation) { - assert(isNotEmpty); - assert(last.key == operation.key); - assert(operation.data is String && last.data is String); - - final length = operation.length! + last.length!; - final lastText = last.data as String; - final opText = operation.data as String; - final resultText = lastText + opText; - final index = operations.length; - operations.replaceRange(index - 1, index, [ - Operation(operation.key, length, resultText, operation.attributes), - ]); - } - - /// Pushes new operation into this delta. - /// - /// Performs compaction by composing [operation] with current tail operation - /// of this delta, when possible. For instance, if current tail is - /// `insert('abc')` and pushed operation is `insert('123')` then existing - /// tail is replaced with `insert('abc123')` - a compound result of the two - /// operations. - void push(Operation operation) { - if (operation.isEmpty) return; - - var index = operations.length; - final lastOp = operations.isNotEmpty ? operations.last : null; - if (lastOp != null) { - if (lastOp.isDelete && operation.isDelete) { - _mergeWithTail(operation); - return; - } - - if (lastOp.isDelete && operation.isInsert) { - index -= 1; // Always insert before deleting - final nLastOp = (index > 0) ? operations.elementAt(index - 1) : null; - if (nLastOp == null) { - operations.insert(0, operation); - return; - } - } - - if (lastOp.isInsert && operation.isInsert) { - if (lastOp.hasSameAttributes(operation) && - operation.data is String && - lastOp.data is String) { - _mergeWithTail(operation); - return; - } - } - - if (lastOp.isRetain && operation.isRetain) { - if (lastOp.hasSameAttributes(operation)) { - _mergeWithTail(operation); - return; - } - } - } - if (index == operations.length) { - operations.add(operation); - } else { - final opAtIndex = operations.elementAt(index); - operations.replaceRange(index, index + 1, [operation, opAtIndex]); - } - modificationCount++; - } - - /// Composes next operation from [thisIter] and [otherIter]. - /// - /// Returns new operation or `null` if operations from [thisIter] and - /// [otherIter] nullify each other. For instance, for the pair `insert('abc')` - /// and `delete(3)` composition result would be empty string. - Operation? _composeOperation( - DeltaIterator thisIter, DeltaIterator otherIter) { - if (otherIter.isNextInsert) return otherIter.next(); - if (thisIter.isNextDelete) return thisIter.next(); - - final length = math.min(thisIter.peekLength(), otherIter.peekLength()); - final thisOp = thisIter.next(length); - final otherOp = otherIter.next(length); - assert(thisOp.length == otherOp.length); - - if (otherOp.isRetain) { - final attributes = composeAttributes( - thisOp.attributes, - otherOp.attributes, - keepNull: thisOp.isRetain, - ); - if (thisOp.isRetain) { - return Operation.retain(thisOp.length, attributes); - } else if (thisOp.isInsert) { - return Operation.insert(thisOp.data, attributes); - } else { - throw StateError('Unreachable'); - } - } else { - // otherOp == delete && thisOp in [retain, insert] - assert(otherOp.isDelete); - if (thisOp.isRetain) return otherOp; - assert(thisOp.isInsert); - // otherOp(delete) + thisOp(insert) => null - } - return null; - } - - /// Composes this delta with [other] and returns new [Delta]. - /// - /// It is not required for this and [other] delta to represent a document - /// delta (consisting only of insert operations). - Delta compose(Delta other) { - final result = Delta(); - final thisIter = DeltaIterator(this); - final otherIter = DeltaIterator(other); - - while (thisIter.hasNext || otherIter.hasNext) { - final newOp = _composeOperation(thisIter, otherIter); - if (newOp != null) result.push(newOp); - } - return result..trim(); - } - - /// Returns a new lazy Iterable with elements that are created by calling - /// f on each element of this Iterable in iteration order. - /// - /// Convenience method - Iterable map(T Function(Operation) f) { - return operations.map(f); - } - - /// Returns a [Delta] containing differences between 2 [Delta]s. - /// If [cleanupSemantic] is `true` (default), applies the following: - /// - /// The diff of "mouse" and "sofas" is - /// [delete(1), insert("s"), retain(1), - /// delete("u"), insert("fa"), retain(1), delete(1)]. - /// While this is the optimum diff, it is difficult for humans to understand. - /// Semantic cleanup rewrites the diff, - /// expanding it into a more intelligible format. - /// The above example would become: [(-1, "mouse"), (1, "sofas")]. - /// (source: https://github.com/google/diff-match-patch/wiki/API) - /// - /// Useful when one wishes to display difference between 2 documents - Delta diff(Delta other, {bool cleanupSemantic = true}) { - if (operations.equals(other.operations)) { - return Delta(); - } - final stringThis = map((op) { - if (op.isInsert) { - return op.data is String ? op.data : _kNullCharacter; - } - final prep = this == other ? 'on' : 'with'; - throw ArgumentError('diff() call $prep non-document'); - }).join(); - final stringOther = other.map((op) { - if (op.isInsert) { - return op.data is String ? op.data : _kNullCharacter; - } - final prep = this == other ? 'on' : 'with'; - throw ArgumentError('diff() call $prep non-document'); - }).join(); - - final retDelta = Delta(); - final diffResult = dmp.diff(stringThis, stringOther); - if (cleanupSemantic) { - dmp.DiffMatchPatch().diffCleanupSemantic(diffResult); - } - - final thisIter = DeltaIterator(this); - final otherIter = DeltaIterator(other); - - for (final component in diffResult) { - var length = component.text.length; - while (length > 0) { - var opLength = 0; - switch (component.operation) { - case dmp.DIFF_INSERT: - opLength = math.min(otherIter.peekLength(), length); - retDelta.push(otherIter.next(opLength)); - break; - case dmp.DIFF_DELETE: - opLength = math.min(length, thisIter.peekLength()); - thisIter.next(opLength); - retDelta.delete(opLength); - break; - case dmp.DIFF_EQUAL: - opLength = math.min( - math.min(thisIter.peekLength(), otherIter.peekLength()), - length, - ); - final thisOp = thisIter.next(opLength); - final otherOp = otherIter.next(opLength); - if (thisOp.data == otherOp.data) { - retDelta.retain( - opLength, - diffAttributes(thisOp.attributes, otherOp.attributes), - ); - } else { - retDelta - ..push(otherOp) - ..delete(opLength); - } - break; - } - length -= opLength; - } - } - return retDelta..trim(); - } - - /// Transforms next operation from [otherIter] against next operation in - /// [thisIter]. - /// - /// Returns `null` if both operations nullify each other. - Operation? _transformOperation( - DeltaIterator thisIter, DeltaIterator otherIter, bool priority) { - if (thisIter.isNextInsert && (priority || !otherIter.isNextInsert)) { - return Operation.retain(thisIter.next().length); - } else if (otherIter.isNextInsert) { - return otherIter.next(); - } - - final length = math.min(thisIter.peekLength(), otherIter.peekLength()); - final thisOp = thisIter.next(length); - final otherOp = otherIter.next(length); - assert(thisOp.length == otherOp.length); - - // At this point only delete and retain operations are possible. - if (thisOp.isDelete) { - // otherOp is either delete or retain, so they nullify each other. - return null; - } else if (otherOp.isDelete) { - return otherOp; - } else { - // Retain otherOp which is either retain or insert. - return Operation.retain( - length, - transformAttributes(thisOp.attributes, otherOp.attributes, priority), - ); - } - } - - /// Transforms [other] delta against operations in this delta. - Delta transform(Delta other, bool priority) { - final result = Delta(); - final thisIter = DeltaIterator(this); - final otherIter = DeltaIterator(other); - - while (thisIter.hasNext || otherIter.hasNext) { - final newOp = _transformOperation(thisIter, otherIter, priority); - if (newOp != null) result.push(newOp); - } - return result..trim(); - } - - /// Removes trailing retain operation with empty attributes, if present. - void trim() { - if (isNotEmpty) { - final last = operations.last; - if (last.isRetain && last.isPlain) operations.removeLast(); - } - } - - /// Removes trailing '\n' - void _trimNewLine() { - if (isNotEmpty) { - final lastOp = operations.last; - final lastOpData = lastOp.data; - - if (lastOpData is String && lastOpData.endsWith('\n')) { - operations.removeLast(); - if (lastOpData.length > 1) { - insert(lastOpData.substring(0, lastOpData.length - 1), - lastOp.attributes); - } - } - } - } - - /// Concatenates [other] with this delta and returns the result. - Delta concat(Delta other, {bool trimNewLine = false}) { - final result = Delta.from(this); - if (trimNewLine) { - result._trimNewLine(); - } - if (other.isNotEmpty) { - // In case first operation of other can be merged with last operation in - // our list. - result.push(other.operations.first); - result.operations.addAll(other.operations.sublist(1)); - } - return result; - } - - /// Inverts this delta against [base]. - /// - /// Returns new delta which negates effect of this delta when applied to - /// [base]. This is an equivalent of "undo" operation on deltas. - Delta invert(Delta base) { - final inverted = Delta(); - if (base.isEmpty) return inverted; - - var baseIndex = 0; - for (final op in operations) { - if (op.isInsert) { - inverted.delete(op.length!); - } else if (op.isRetain && op.isPlain) { - inverted.retain(op.length!); - baseIndex += op.length!; - } else if (op.isDelete || (op.isRetain && op.isNotPlain)) { - final length = op.length!; - final sliceDelta = base.slice(baseIndex, baseIndex + length); - sliceDelta.toList().forEach((baseOp) { - if (op.isDelete) { - inverted.push(baseOp); - } else if (op.isRetain && op.isNotPlain) { - final invertAttr = - invertAttributes(op.attributes, baseOp.attributes); - inverted.retain( - baseOp.length!, invertAttr.isEmpty ? null : invertAttr); - } - }); - baseIndex += length; - } else { - throw StateError('Unreachable'); - } - } - inverted.trim(); - return inverted; - } - - /// Returns slice of this delta from [start] index (inclusive) to [end] - /// (exclusive). - Delta slice(int start, [int? end]) { - final delta = Delta(); - var index = 0; - final opIterator = DeltaIterator(this); - - final actualEnd = end ?? DeltaIterator.maxLength; - - while (index < actualEnd && opIterator.hasNext) { - Operation op; - if (index < start) { - op = opIterator.next(start - index); - } else { - op = opIterator.next(actualEnd - index); - delta.push(op); - } - index += op.length!; - } - return delta; - } - - /// Transforms [index] against this delta. - /// - /// Any "delete" operation before specified [index] shifts it backward, as - /// well as any "insert" operation shifts it forward. - /// - /// The [force] argument is used to resolve scenarios when there is an - /// insert operation at the same position as [index]. If [force] is set to - /// `true` (default) then position is forced to shift forward, otherwise - /// position stays at the same index. In other words setting [force] to - /// `false` gives higher priority to the transformed position. - /// - /// Useful to adjust caret or selection positions. - int transformPosition(int index, {bool force = true}) { - final iter = DeltaIterator(this); - var offset = 0; - while (iter.hasNext && offset <= index) { - final op = iter.next(); - if (op.isDelete) { - index -= math.min(op.length!, index - offset); - continue; - } else if (op.isInsert && (offset < index || force)) { - index += op.length!; - } - offset += op.length!; - } - return index; - } - - @override - String toString() => operations.join('\n'); -} diff --git a/dart_quill_delta/lib/src/delta/delta_iterator.dart b/dart_quill_delta/lib/src/delta/delta_iterator.dart deleted file mode 100644 index bb8c41e0b..000000000 --- a/dart_quill_delta/lib/src/delta/delta_iterator.dart +++ /dev/null @@ -1,100 +0,0 @@ -import 'dart:math' as math; - -import '../operation/operation.dart'; -import 'delta.dart'; - -/// Specialized iterator for [Delta]s. -class DeltaIterator { - DeltaIterator(this.delta) : _modificationCount = delta.modificationCount; - - static const int maxLength = 1073741824; - - final Delta delta; - final int _modificationCount; - int _index = 0; - int _offset = 0; - - bool get isNextInsert => nextOperationKey == Operation.insertKey; - - bool get isNextDelete => nextOperationKey == Operation.deleteKey; - - bool get isNextRetain => nextOperationKey == Operation.retainKey; - - String? get nextOperationKey { - if (_index < delta.length) { - return delta.elementAt(_index).key; - } else { - return null; - } - } - - bool get hasNext => peekLength() < maxLength; - - /// Returns length of next operation without consuming it. - /// - /// Returns [maxLength] if there is no more operations left to iterate. - int peekLength() { - if (_index < delta.length) { - final operation = delta.operations[_index]; - return operation.length! - _offset; - } - return maxLength; - } - - /// Consumes and returns next operation. - /// - /// Optional [length] specifies maximum length of operation to return. Note - /// that actual length of returned operation may be less than specified value. - /// - /// If this iterator reached the end of the Delta then returns a retain - /// operation with its length set to [maxLength]. - // TODO: Note that we used double.infinity as the default value - // for length here - // but this can now cause a type error since operation length is - // expected to be an int. Changing default length to [maxLength] is - // a workaround to avoid breaking changes. - Operation next([int length = maxLength]) { - if (_modificationCount != delta.modificationCount) { - throw ConcurrentModificationError(delta); - } - - if (_index < delta.length) { - final op = delta.elementAt(_index); - final opKey = op.key; - final opAttributes = op.attributes; - final currentOffset = _offset; - final actualLength = math.min(op.length! - currentOffset, length); - if (actualLength == op.length! - currentOffset) { - _index++; - _offset = 0; - } else { - _offset += actualLength; - } - final opData = op.isInsert && op.data is String - ? (op.data as String) - .substring(currentOffset, currentOffset + actualLength) - : op.data; - final opIsNotEmpty = - opData is String ? opData.isNotEmpty : true; // embeds are never empty - final opLength = opData is String ? opData.length : 1; - final opActualLength = opIsNotEmpty ? opLength : actualLength; - return Operation(opKey, opActualLength, opData, opAttributes); - } - return Operation.retain(length); - } - - /// Skips [length] characters in source delta. - /// - /// Returns last skipped operation, or `null` if there was nothing to skip. - Operation? skip(int length) { - var skipped = 0; - Operation? op; - while (skipped < length && hasNext) { - final opLength = peekLength(); - final skip = math.min(length - skipped, opLength); - op = next(skip); - skipped += op.length!; - } - return op; - } -} diff --git a/dart_quill_delta/lib/src/operation/operation.dart b/dart_quill_delta/lib/src/operation/operation.dart deleted file mode 100644 index 126942ae5..000000000 --- a/dart_quill_delta/lib/src/operation/operation.dart +++ /dev/null @@ -1,171 +0,0 @@ -import 'package:collection/collection.dart'; -import 'package:quiver/core.dart'; - -/// Decoder function to convert raw `data` object into a user-defined data type. -/// -/// Useful with embedded content. -typedef DataDecoder = Object? Function(Object data); - -/// Default data decoder which simply passes through the original value. -Object? _passThroughDataDecoder(Object? data) => data; - -const _attributeEquality = DeepCollectionEquality(); -const _valueEquality = DeepCollectionEquality(); - -/// Operation performed on a rich-text document. -class Operation { - Operation(this.key, this.length, this.data, Map? attributes) - : assert(_validKeys.contains(key), 'Invalid operation key "$key".'), - assert(() { - if (key != Operation.insertKey) return true; - return data is String ? data.length == length : length == 1; - }(), 'Length of insert operation must be equal to the data length.'), - _attributes = - attributes != null ? Map.from(attributes) : null; - - /// Creates operation which deletes [length] of characters. - factory Operation.delete(int length) => - Operation(Operation.deleteKey, length, '', null); - - /// Creates operation which inserts [text] with optional [attributes]. - factory Operation.insert(dynamic data, [Map? attributes]) => - Operation(Operation.insertKey, data is String ? data.length : 1, data, - attributes); - - /// Creates operation which retains [length] of characters and optionally - /// applies attributes. - factory Operation.retain(int? length, [Map? attributes]) => - Operation(Operation.retainKey, length, '', attributes); - - /// Key of insert operations. - static const String insertKey = 'insert'; - - /// Key of delete operations. - static const String deleteKey = 'delete'; - - /// Key of retain operations. - static const String retainKey = 'retain'; - - /// Key of attributes collection. - static const String attributesKey = 'attributes'; - - static const List _validKeys = [insertKey, deleteKey, retainKey]; - - /// Key of this operation, can be "insert", "delete" or "retain". - final String key; - - /// Length of this operation. - final int? length; - - /// Payload of "insert" operation, for other types is set to empty string. - final Object? data; - - /// Rich-text attributes set by this operation, can be `null`. - Map? get attributes => - _attributes == null ? null : Map.from(_attributes); - final Map? _attributes; - - /// Creates new [Operation] from JSON payload. - /// - /// If `dataDecoder` parameter is not null then it is used to additionally - /// decode the operation's data object. Only applied to insert operations. - static Operation fromJson(Map data, {DataDecoder? dataDecoder}) { - dataDecoder ??= _passThroughDataDecoder; - final map = Map.from(data); - if (map.containsKey(Operation.insertKey)) { - final data = dataDecoder(map[Operation.insertKey]); - final dataLength = data is String ? data.length : 1; - return Operation( - Operation.insertKey, dataLength, data, map[Operation.attributesKey]); - } else if (map.containsKey(Operation.deleteKey)) { - final int? length = map[Operation.deleteKey]; - return Operation(Operation.deleteKey, length, '', null); - } else if (map.containsKey(Operation.retainKey)) { - final int? length = map[Operation.retainKey]; - return Operation( - Operation.retainKey, length, '', map[Operation.attributesKey]); - } - throw ArgumentError.value(data, 'Invalid data for Delta operation.'); - } - - /// Returns JSON-serializable representation of this operation. - Map toJson() { - final json = {key: value}; - if (_attributes != null) json[Operation.attributesKey] = attributes; - return json; - } - - /// Returns value of this operation. - /// - /// For insert operations this returns text, for delete and retain - length. - dynamic get value => (key == Operation.insertKey) ? data : length; - - /// Returns `true` if this is a delete operation. - bool get isDelete => key == Operation.deleteKey; - - /// Returns `true` if this is an insert operation. - bool get isInsert => key == Operation.insertKey; - - /// Returns `true` if this is a retain operation. - bool get isRetain => key == Operation.retainKey; - - /// Returns `true` if this operation has no attributes, e.g. is plain text. - bool get isPlain => _attributes == null || _attributes.isEmpty; - - /// Returns `true` if this operation sets at least one attribute. - bool get isNotPlain => !isPlain; - - /// Returns `true` is this operation is empty. - /// - /// An operation is considered empty if its [length] is equal to `0`. - bool get isEmpty => length == 0; - - /// Returns `true` is this operation is not empty. - bool get isNotEmpty => length! > 0; - - @override - bool operator ==(other) { - if (identical(this, other)) return true; - if (other is! Operation) return false; - final typedOther = other; - return key == typedOther.key && - length == typedOther.length && - _valueEquality.equals(data, typedOther.data) && - hasSameAttributes(typedOther); - } - - /// Returns `true` if this operation has attribute specified by [name]. - bool hasAttribute(String name) => - isNotPlain && _attributes!.containsKey(name); - - /// Returns `true` if [other] operation has the same attributes as this one. - bool hasSameAttributes(Operation other) { - // treat null and empty equal - if ((_attributes?.isEmpty ?? true) && - (other._attributes?.isEmpty ?? true)) { - return true; - } - return _attributeEquality.equals(_attributes, other._attributes); - } - - @override - int get hashCode { - if (_attributes != null && _attributes.isNotEmpty) { - final attrsHash = - hashObjects(_attributes.entries.map((e) => hash2(e.key, e.value))); - return hash3(key, value, attrsHash); - } - return hash2(key, value); - } - - @override - String toString() { - final attr = attributes == null ? '' : ' + $attributes'; - final text = isInsert - ? (data is String - ? (data as String).replaceAll('\n', '⏎') - : data.toString()) - : '$length'; - return '$key⟨ $text ⟩$attr'; - } -} diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml deleted file mode 100644 index f52527a58..000000000 --- a/dart_quill_delta/pubspec.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: dart_quill_delta -description: A port of quill-js-delta from typescript to dart -version: 10.8.0 -homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ -repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ -issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ -documentation: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ - -environment: - sdk: ^3.2.3 - -dependencies: - collection: ^1.17.0 - diff_match_patch: ^0.4.1 - quiver: ^3.2.1 - -dev_dependencies: - # TODO: Using 4.0.0 to not require higher version of Dart SDK - lints: ^4.0.0 - test: ^1.24.0 diff --git a/dart_quill_delta/test/dart_quill_delta_test.dart b/dart_quill_delta/test/dart_quill_delta_test.dart deleted file mode 100644 index 7de0162a4..000000000 --- a/dart_quill_delta/test/dart_quill_delta_test.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:test/test.dart'; - -void main() { - group('A group of tests', () { - setUp(() { - // Additional setup goes here. - }); - - test('First Test', () {}); - }); -} diff --git a/doc/delta_introduction.md b/doc/delta_introduction.md index 4f92cb7ba..70abd9808 100644 --- a/doc/delta_introduction.md +++ b/doc/delta_introduction.md @@ -13,7 +13,7 @@ These operations are combined to describe any change in the document's state. You can import `Delta` and `Operation` class using: ```dart -import 'package:flutter_quill/dart_quill_delta.dart'; +import 'package:flutter_quill/quill_delta.dart'; ``` # What is a `Operation`? @@ -51,7 +51,7 @@ An insertion adds new content to the document. The `Insert` operation contains t Example of `Insert` operation: ```dart -import 'package:flutter_quill/dart_quill_delta.dart'; +import 'package:flutter_quill/quill_delta.dart'; void main() { // Create a Delta with a text insertion @@ -120,7 +120,7 @@ Example of `Delete` operation using `QuillController` ```dart import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/dart_quill_delta.dart'; +import 'package:flutter_quill/quill_delta.dart'; QuillController _quillController = QuillController( document: Document.fromJson([{'insert': 'Hello, world!'}]), @@ -186,7 +186,7 @@ Using Directly `Delta` class: ```dart import 'package:flutter_quill/flutter_quill.dart'; -import 'package:flutter_quill/dart_quill_delta.dart'; +import 'package:flutter_quill/quill_delta.dart'; void main() { // Create a Delta that retains 10 characters @@ -218,7 +218,7 @@ Deltas to combine: ```dart -import 'package:flutter_quill/dart_quill_delta.dart' as quill; +import 'package:flutter_quill/quill_delta.dart' as quill; void main() { // Defining Delta A @@ -248,7 +248,7 @@ Deltas to combine: - **Delta B**: `[{retain: 6}, {delete: 5}, {insert: "Flutter"}]` ```dart -import 'package:flutter_quill/dart_quill_delta.dart' as quill; +import 'package:flutter_quill/quill_delta.dart' as quill; void main() { diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 1ae5c5a1f..bfba6a35a 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -56,8 +56,6 @@ dependency_overrides: path: ../ flutter_quill_extensions: path: ../flutter_quill_extensions - dart_quill_delta: - path: ../dart_quill_delta flutter_quill_test: path: ../flutter_quill_test diff --git a/scripts/packages.dart b/scripts/packages.dart index 0ad09cd6e..0f1e9fe99 100644 --- a/scripts/packages.dart +++ b/scripts/packages.dart @@ -1,7 +1,6 @@ /// The list of the packages in the repository. const repoPackages = [ './', - './dart_quill_delta', './flutter_quill_extensions', './flutter_quill_test', ]; From 5f6dff280b75ed23309c7cefce15630e9ff8f38a Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 27 Sep 2024 22:47:50 +0300 Subject: [PATCH 069/113] docs(readme): update flutter_keyboard_visibility to flutter_keyboard_visibility_temp_fork in plugins section --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d314ce643..e8e12ee71 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ The `flutter_quill` package uses the following plugins: 1. [`url_launcher`](https://pub.dev/packages/url_launcher) to open links. 2. [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge) to access platform-specific APIs for the editor. -3. [`flutter_keyboard_visibility`](https://pub.dev/packages/flutter_keyboard_visibility) to listen for keyboard +3. [`flutter_keyboard_visibility_temp_fork`](https://pub.dev/packages/flutter_keyboard_visibility_temp_fork) to listen for keyboard visibility changes. From bafa87da26157c9e06469233e94a6dae22cd2a0f Mon Sep 17 00:00:00 2001 From: Ellet Date: Fri, 27 Sep 2024 22:51:08 +0300 Subject: [PATCH 070/113] chore: remove .pubignore --- .pubignore | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 .pubignore diff --git a/.pubignore b/.pubignore deleted file mode 100644 index 15f51beec..000000000 --- a/.pubignore +++ /dev/null @@ -1,13 +0,0 @@ -# For local development -pubspec_overrides.yaml -pubspec_overrides.yaml.disabled - -# Github -.github/ - -# The example -example/.fvm/ -example/build/ -example/.dart_tool/ - -scripts/ \ No newline at end of file From 8d6e401ad8e5a6982bd2efaedfe82950d5cb078c Mon Sep 17 00:00:00 2001 From: EchoEllet Date: Fri, 27 Sep 2024 20:58:20 +0000 Subject: [PATCH 071/113] chore(version): update to version 10.8.1 --- CHANGELOG.md | 24 ++++++++++++++++++++++++ CHANGELOG_DATA.json | 1 + flutter_quill_extensions/CHANGELOG.md | 24 ++++++++++++++++++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 24 ++++++++++++++++++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 7 files changed, 76 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff9e817c8..89b553bd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file. +## 10.8.1 + +- This release fixes the compilation issue when building the project with [Flutter/Wasm](https://docs.flutter.dev/platform-integration/web/wasm) target on the web. Also, update the conditional import check to avoid using `dart.library.html`: + + ```dart + import 'web/quill_controller_web_stub.dart' + if (dart.library.html) 'web/quill_controller_web_real.dart'; + ``` + + To fix critical bugs that prevent using the editor on Wasm. + + > Flutter/Wasm is stable as of [Flutter 3.22](https://medium.com/flutter/whats-new-in-flutter-3-22-fbde6c164fe3) though it's likely that you might experience some issues when using this new target, if you experienced any issues related to Wasm support related to Flutter Quill, feel free to [open an issue](https://github.com/singerdmx/flutter-quill/issues). + + Issue #1889 is fixed by temporarily replacing the plugin [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) with [flutter_keyboard_visibility_temp_fork](https://pub.dev/packages/flutter_keyboard_visibility_temp_fork) since `flutter_keyboard_visibility` depend on `dart:html`. Also updated the `compileSdkVersion` to `34` instead of `31` as a workaround to [Flutter #63533](https://github.com/flutter/flutter/issues/63533). + +- Support for Hungarian (hu) localization was added by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2291. +- [dart_quill_delta](https://pub.dev/packages/dart_quill_delta/) has been moved to [FlutterQuill/dart-quill-delta](https://github.com/FlutterQuill/dart-quill-delta) (outside of this repo) and they have separated version now. + + +## New Contributors +* @G-Greg made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2291 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.0...v10.8.1 + ## 10.8.0 > [!CAUTION] diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index 335a2872b..b9f6a97d4 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.8.1": "- This release fixes the compilation issue when building the project with [Flutter/Wasm](https://docs.flutter.dev/platform-integration/web/wasm) target on the web. Also, update the conditional import check to avoid using `dart.library.html`:\r\n\r\n ```dart\r\n import 'web/quill_controller_web_stub.dart'\r\n if (dart.library.html) 'web/quill_controller_web_real.dart';\r\n ```\r\n \r\n To fix critical bugs that prevent using the editor on Wasm.\r\n \r\n > Flutter/Wasm is stable as of [Flutter 3.22](https://medium.com/flutter/whats-new-in-flutter-3-22-fbde6c164fe3) though it's likely that you might experience some issues when using this new target, if you experienced any issues related to Wasm support related to Flutter Quill, feel free to [open an issue](https://github.com/singerdmx/flutter-quill/issues).\r\n \r\n Issue #1889 is fixed by temporarily replacing the plugin [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) with [flutter_keyboard_visibility_temp_fork](https://pub.dev/packages/flutter_keyboard_visibility_temp_fork) since `flutter_keyboard_visibility` depend on `dart:html`. Also updated the `compileSdkVersion` to `34` instead of `31` as a workaround to [Flutter #63533](https://github.com/flutter/flutter/issues/63533).\r\n\r\n- Support for Hungarian (hu) localization was added by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2291.\r\n- [dart_quill_delta](https://pub.dev/packages/dart_quill_delta/) has been moved to [FlutterQuill/dart-quill-delta](https://github.com/FlutterQuill/dart-quill-delta) (outside of this repo) and they have separated version now.\r\n\r\n\r\n## New Contributors\r\n* @G-Greg made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2291\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.0...v10.8.1", "10.8.0": "> [!CAUTION]\r\n> This release can be breaking change for `flutter_quill_extensions` users as it remove the built-in support for loading YouTube videos\r\n\r\nIf you're using [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) then this release, can be a breaking change for you if you load videos in the editor and expect YouTube videos to be supported, [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) and [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) are no longer dependencies of the extensions package, which are used to support loading YouTube Iframe videos on non-web platforms, more details about the discussion and reasons in [#2286](https://github.com/singerdmx/flutter-quill/pull/2286) and [#2284](https://github.com/singerdmx/flutter-quill/issues/2284).\r\n\r\nWe have added an experimental property that gives you more flexibility and control about the implementation you want to use for loading videos.\r\n\r\n> [!WARNING]\r\n> It's likely to experience some common issues while implementing this feature, especially on desktop platforms as the support for [flutter_inappwebview_windows](https://pub.dev/packages/flutter_inappwebview_windows) and [flutter_inappwebview_macos](https://pub.dev/packages/flutter_inappwebview_macos) before 2 days. Some of the issues are in the Flutter Quill editor.\r\n\r\nIf you want loading YouTube videos to be a feature again with the latest version of Flutter Quill, you can use an existing plugin or package, or implement your own solution. For example, you might use [`youtube_video_player`](https://pub.dev/packages/youtube_video_player) or [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter), which was previously used in [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions).\r\n\r\nHere’s an example setup using `youtube_player_flutter`:\r\n\r\n```shell\r\nflutter pub add youtube_player_flutter\r\n```\r\n\r\nExample widget configuration:\r\n\r\n```dart\r\nimport 'package:flutter/material.dart';\r\nimport 'package:youtube_player_flutter/youtube_player_flutter.dart';\r\n\r\nclass YoutubeVideoPlayer extends StatefulWidget {\r\n const YoutubeVideoPlayer({required this.videoUrl, super.key});\r\n\r\n final String videoUrl;\r\n\r\n @override\r\n State createState() => _YoutubeVideoPlayerState();\r\n}\r\n\r\nclass _YoutubeVideoPlayerState extends State {\r\n late final YoutubePlayerController _youtubePlayerController;\r\n @override\r\n void initState() {\r\n super.initState();\r\n _youtubePlayerController = YoutubePlayerController(\r\n initialVideoId: YoutubePlayer.convertUrlToId(widget.videoUrl) ??\r\n (throw StateError('Expect a valid video URL')),\r\n flags: const YoutubePlayerFlags(\r\n autoPlay: true,\r\n mute: true,\r\n ),\r\n );\r\n }\r\n\r\n @override\r\n Widget build(BuildContext context) {\r\n return YoutubePlayer(\r\n controller: _youtubePlayerController,\r\n showVideoProgressIndicator: true,\r\n );\r\n }\r\n\r\n @override\r\n void dispose() {\r\n _youtubePlayerController.dispose();\r\n super.dispose();\r\n }\r\n}\r\n\r\n```\r\n\r\nThen, integrate it with `QuillEditorVideoEmbedConfigurations`\r\n\r\n```dart\r\nFlutterQuillEmbeds.editorBuilders(\r\n videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations(\r\n customVideoBuilder: (videoUrl, readOnly) {\r\n // Example: Check for YouTube Video URL and return your\r\n // YouTube video widget here.\r\n bool isYouTubeUrl(String videoUrl) {\r\n try {\r\n final uri = Uri.parse(videoUrl);\r\n return uri.host == 'www.youtube.com' ||\r\n uri.host == 'youtube.com' ||\r\n uri.host == 'youtu.be' ||\r\n uri.host == 'www.youtu.be';\r\n } catch (_) {\r\n return false;\r\n }\r\n }\r\n\r\n if (isYouTubeUrl(videoUrl)) {\r\n return YoutubeVideoPlayer(\r\n videoUrl: videoUrl,\r\n );\r\n }\r\n\r\n // Return null to fallback to the default logic\r\n return null;\r\n },\r\n ignoreYouTubeSupport: true,\r\n ),\r\n);\r\n```\r\n\r\n> [!NOTE]\r\n> This example illustrates a basic approach, additional adjustments might be necessary to meet your specific needs. YouTube video support is no longer included in this project. Keep in mind that `customVideoBuilder` is experimental and can change without being considered as breaking change. More details in [breaking changes](https://github.com/singerdmx/flutter-quill#-breaking-changes) section.\r\n\r\n[`super_clipboard`](https://pub.dev/packages/super_clipboard) will also no longer a dependency of `flutter_quill_extensions` once [PR #2230](https://github.com/singerdmx/flutter-quill/pull/2230) is ready.\r\n\r\nWe're looking forward to your feedback.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.7...v10.8.0", "10.7.7": "This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230)\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.6...v10.7.7", "10.7.6": "* Code Comments Typo fixes by @Luismi74 in https://github.com/singerdmx/flutter-quill/pull/2267\r\n* docs: add important note for contributors before introducing new features by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2269\r\n* docs(readme): add 'Breaking Changes' section by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2275\r\n* Fix: Resolved issue with broken IME composing rect in Windows desktop(re-implementation) by @agata in https://github.com/singerdmx/flutter-quill/pull/2282\r\n\r\n## New Contributors\r\n* @Luismi74 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2267\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.5...v10.7.6", diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index ff9e817c8..89b553bd8 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file. +## 10.8.1 + +- This release fixes the compilation issue when building the project with [Flutter/Wasm](https://docs.flutter.dev/platform-integration/web/wasm) target on the web. Also, update the conditional import check to avoid using `dart.library.html`: + + ```dart + import 'web/quill_controller_web_stub.dart' + if (dart.library.html) 'web/quill_controller_web_real.dart'; + ``` + + To fix critical bugs that prevent using the editor on Wasm. + + > Flutter/Wasm is stable as of [Flutter 3.22](https://medium.com/flutter/whats-new-in-flutter-3-22-fbde6c164fe3) though it's likely that you might experience some issues when using this new target, if you experienced any issues related to Wasm support related to Flutter Quill, feel free to [open an issue](https://github.com/singerdmx/flutter-quill/issues). + + Issue #1889 is fixed by temporarily replacing the plugin [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) with [flutter_keyboard_visibility_temp_fork](https://pub.dev/packages/flutter_keyboard_visibility_temp_fork) since `flutter_keyboard_visibility` depend on `dart:html`. Also updated the `compileSdkVersion` to `34` instead of `31` as a workaround to [Flutter #63533](https://github.com/flutter/flutter/issues/63533). + +- Support for Hungarian (hu) localization was added by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2291. +- [dart_quill_delta](https://pub.dev/packages/dart_quill_delta/) has been moved to [FlutterQuill/dart-quill-delta](https://github.com/FlutterQuill/dart-quill-delta) (outside of this repo) and they have separated version now. + + +## New Contributors +* @G-Greg made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2291 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.0...v10.8.1 + ## 10.8.0 > [!CAUTION] diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 38d6a241d..1c0e94b5d 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.8.0 +version: 10.8.1 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index ff9e817c8..89b553bd8 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file. +## 10.8.1 + +- This release fixes the compilation issue when building the project with [Flutter/Wasm](https://docs.flutter.dev/platform-integration/web/wasm) target on the web. Also, update the conditional import check to avoid using `dart.library.html`: + + ```dart + import 'web/quill_controller_web_stub.dart' + if (dart.library.html) 'web/quill_controller_web_real.dart'; + ``` + + To fix critical bugs that prevent using the editor on Wasm. + + > Flutter/Wasm is stable as of [Flutter 3.22](https://medium.com/flutter/whats-new-in-flutter-3-22-fbde6c164fe3) though it's likely that you might experience some issues when using this new target, if you experienced any issues related to Wasm support related to Flutter Quill, feel free to [open an issue](https://github.com/singerdmx/flutter-quill/issues). + + Issue #1889 is fixed by temporarily replacing the plugin [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) with [flutter_keyboard_visibility_temp_fork](https://pub.dev/packages/flutter_keyboard_visibility_temp_fork) since `flutter_keyboard_visibility` depend on `dart:html`. Also updated the `compileSdkVersion` to `34` instead of `31` as a workaround to [Flutter #63533](https://github.com/flutter/flutter/issues/63533). + +- Support for Hungarian (hu) localization was added by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2291. +- [dart_quill_delta](https://pub.dev/packages/dart_quill_delta/) has been moved to [FlutterQuill/dart-quill-delta](https://github.com/FlutterQuill/dart-quill-delta) (outside of this repo) and they have separated version now. + + +## New Contributors +* @G-Greg made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2291 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.0...v10.8.1 + ## 10.8.0 > [!CAUTION] diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 9fe894518..814a275d0 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.8.0 +version: 10.8.1 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 5454b4ae1..21dd14fae 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.8.0 +version: 10.8.1 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From c9cdadf9d53425d6ed2b6d0686115e854ffd9678 Mon Sep 17 00:00:00 2001 From: Ellet Date: Sat, 28 Sep 2024 12:00:10 +0300 Subject: [PATCH 072/113] fix(ci): use fixed version of simple_spell_checker to fix CI warnings --- example/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index bfba6a35a..d87d3c7c3 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: equatable: ^2.0.5 cross_file: ^0.3.4 cached_network_image: ^3.3.1 - simple_spell_checker: ^1.2.1 + simple_spell_checker: 1.2.1 # Bloc libraries bloc: ^8.1.4 From 59810e9912beeb19cb1c809b248ff89eb269c4f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9ts=20Gerg=C5=91?= Date: Tue, 1 Oct 2024 14:02:52 +0200 Subject: [PATCH 073/113] Fixed minor typo in Hungarian (hu) localization (#2307) * fixed "link link" typo to "link" --- lib/src/l10n/generated/quill_localizations_hu.dart | 2 +- lib/src/l10n/quill_hu.arb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/l10n/generated/quill_localizations_hu.dart b/lib/src/l10n/generated/quill_localizations_hu.dart index 17365b96d..6b5eedf5c 100644 --- a/lib/src/l10n/generated/quill_localizations_hu.dart +++ b/lib/src/l10n/generated/quill_localizations_hu.dart @@ -242,7 +242,7 @@ class FlutterQuillLocalizationsHu extends FlutterQuillLocalizations { @override String get pleaseEnterTheLinkURL => - 'Kérjük, írja be a link link URL-t (pl. \'https://example.com\')'; + 'Kérjük, írja be a link URL-t (pl. \'https://example.com\')'; @override String get pleaseEnterAValidImageURL => diff --git a/lib/src/l10n/quill_hu.arb b/lib/src/l10n/quill_hu.arb index 65895dfed..0281a1507 100644 --- a/lib/src/l10n/quill_hu.arb +++ b/lib/src/l10n/quill_hu.arb @@ -89,7 +89,7 @@ }, "errorWhileSavingImage": "Hiba a kép mentése közben", "pleaseEnterTextForYourLink": "Kérjük, írja be a link szövegét (pl. „További információ”).", - "pleaseEnterTheLinkURL": "Kérjük, írja be a link link URL-t (pl. 'https://example.com')", + "pleaseEnterTheLinkURL": "Kérjük, írja be a link URL-t (pl. 'https://example.com')", "pleaseEnterAValidImageURL": "Kérjük, adjon meg egy érvényes kép URL-t", "pleaseEnterAValidVideoURL": "Kérjük, adjon meg egy érvényes videó URL-t", "photo": "Fénykép", From 37529b0ac8f42b1fc4ea510ee6a652faca33891b Mon Sep 17 00:00:00 2001 From: singerdmx Date: Tue, 1 Oct 2024 18:10:01 +0000 Subject: [PATCH 074/113] chore(version): update to version 10.8.2 --- CHANGELOG.md | 7 +++++++ CHANGELOG_DATA.json | 1 + flutter_quill_extensions/CHANGELOG.md | 7 +++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 7 +++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 7 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89b553bd8..a816d0add 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.8.2 + +* Fixed minor typo in Hungarian (hu) localization by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2307 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.1...v10.8.2 + ## 10.8.1 - This release fixes the compilation issue when building the project with [Flutter/Wasm](https://docs.flutter.dev/platform-integration/web/wasm) target on the web. Also, update the conditional import check to avoid using `dart.library.html`: diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index b9f6a97d4..3e57b98c9 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.8.2": "* Fixed minor typo in Hungarian (hu) localization by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2307\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.1...v10.8.2", "10.8.1": "- This release fixes the compilation issue when building the project with [Flutter/Wasm](https://docs.flutter.dev/platform-integration/web/wasm) target on the web. Also, update the conditional import check to avoid using `dart.library.html`:\r\n\r\n ```dart\r\n import 'web/quill_controller_web_stub.dart'\r\n if (dart.library.html) 'web/quill_controller_web_real.dart';\r\n ```\r\n \r\n To fix critical bugs that prevent using the editor on Wasm.\r\n \r\n > Flutter/Wasm is stable as of [Flutter 3.22](https://medium.com/flutter/whats-new-in-flutter-3-22-fbde6c164fe3) though it's likely that you might experience some issues when using this new target, if you experienced any issues related to Wasm support related to Flutter Quill, feel free to [open an issue](https://github.com/singerdmx/flutter-quill/issues).\r\n \r\n Issue #1889 is fixed by temporarily replacing the plugin [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) with [flutter_keyboard_visibility_temp_fork](https://pub.dev/packages/flutter_keyboard_visibility_temp_fork) since `flutter_keyboard_visibility` depend on `dart:html`. Also updated the `compileSdkVersion` to `34` instead of `31` as a workaround to [Flutter #63533](https://github.com/flutter/flutter/issues/63533).\r\n\r\n- Support for Hungarian (hu) localization was added by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2291.\r\n- [dart_quill_delta](https://pub.dev/packages/dart_quill_delta/) has been moved to [FlutterQuill/dart-quill-delta](https://github.com/FlutterQuill/dart-quill-delta) (outside of this repo) and they have separated version now.\r\n\r\n\r\n## New Contributors\r\n* @G-Greg made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2291\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.0...v10.8.1", "10.8.0": "> [!CAUTION]\r\n> This release can be breaking change for `flutter_quill_extensions` users as it remove the built-in support for loading YouTube videos\r\n\r\nIf you're using [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) then this release, can be a breaking change for you if you load videos in the editor and expect YouTube videos to be supported, [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) and [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) are no longer dependencies of the extensions package, which are used to support loading YouTube Iframe videos on non-web platforms, more details about the discussion and reasons in [#2286](https://github.com/singerdmx/flutter-quill/pull/2286) and [#2284](https://github.com/singerdmx/flutter-quill/issues/2284).\r\n\r\nWe have added an experimental property that gives you more flexibility and control about the implementation you want to use for loading videos.\r\n\r\n> [!WARNING]\r\n> It's likely to experience some common issues while implementing this feature, especially on desktop platforms as the support for [flutter_inappwebview_windows](https://pub.dev/packages/flutter_inappwebview_windows) and [flutter_inappwebview_macos](https://pub.dev/packages/flutter_inappwebview_macos) before 2 days. Some of the issues are in the Flutter Quill editor.\r\n\r\nIf you want loading YouTube videos to be a feature again with the latest version of Flutter Quill, you can use an existing plugin or package, or implement your own solution. For example, you might use [`youtube_video_player`](https://pub.dev/packages/youtube_video_player) or [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter), which was previously used in [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions).\r\n\r\nHere’s an example setup using `youtube_player_flutter`:\r\n\r\n```shell\r\nflutter pub add youtube_player_flutter\r\n```\r\n\r\nExample widget configuration:\r\n\r\n```dart\r\nimport 'package:flutter/material.dart';\r\nimport 'package:youtube_player_flutter/youtube_player_flutter.dart';\r\n\r\nclass YoutubeVideoPlayer extends StatefulWidget {\r\n const YoutubeVideoPlayer({required this.videoUrl, super.key});\r\n\r\n final String videoUrl;\r\n\r\n @override\r\n State createState() => _YoutubeVideoPlayerState();\r\n}\r\n\r\nclass _YoutubeVideoPlayerState extends State {\r\n late final YoutubePlayerController _youtubePlayerController;\r\n @override\r\n void initState() {\r\n super.initState();\r\n _youtubePlayerController = YoutubePlayerController(\r\n initialVideoId: YoutubePlayer.convertUrlToId(widget.videoUrl) ??\r\n (throw StateError('Expect a valid video URL')),\r\n flags: const YoutubePlayerFlags(\r\n autoPlay: true,\r\n mute: true,\r\n ),\r\n );\r\n }\r\n\r\n @override\r\n Widget build(BuildContext context) {\r\n return YoutubePlayer(\r\n controller: _youtubePlayerController,\r\n showVideoProgressIndicator: true,\r\n );\r\n }\r\n\r\n @override\r\n void dispose() {\r\n _youtubePlayerController.dispose();\r\n super.dispose();\r\n }\r\n}\r\n\r\n```\r\n\r\nThen, integrate it with `QuillEditorVideoEmbedConfigurations`\r\n\r\n```dart\r\nFlutterQuillEmbeds.editorBuilders(\r\n videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations(\r\n customVideoBuilder: (videoUrl, readOnly) {\r\n // Example: Check for YouTube Video URL and return your\r\n // YouTube video widget here.\r\n bool isYouTubeUrl(String videoUrl) {\r\n try {\r\n final uri = Uri.parse(videoUrl);\r\n return uri.host == 'www.youtube.com' ||\r\n uri.host == 'youtube.com' ||\r\n uri.host == 'youtu.be' ||\r\n uri.host == 'www.youtu.be';\r\n } catch (_) {\r\n return false;\r\n }\r\n }\r\n\r\n if (isYouTubeUrl(videoUrl)) {\r\n return YoutubeVideoPlayer(\r\n videoUrl: videoUrl,\r\n );\r\n }\r\n\r\n // Return null to fallback to the default logic\r\n return null;\r\n },\r\n ignoreYouTubeSupport: true,\r\n ),\r\n);\r\n```\r\n\r\n> [!NOTE]\r\n> This example illustrates a basic approach, additional adjustments might be necessary to meet your specific needs. YouTube video support is no longer included in this project. Keep in mind that `customVideoBuilder` is experimental and can change without being considered as breaking change. More details in [breaking changes](https://github.com/singerdmx/flutter-quill#-breaking-changes) section.\r\n\r\n[`super_clipboard`](https://pub.dev/packages/super_clipboard) will also no longer a dependency of `flutter_quill_extensions` once [PR #2230](https://github.com/singerdmx/flutter-quill/pull/2230) is ready.\r\n\r\nWe're looking forward to your feedback.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.7...v10.8.0", "10.7.7": "This version is nearly identical to `10.7.6` with a build failure bug fix in [#2283](https://github.com/singerdmx/flutter-quill/pull/2283) related to unmerged change in [#2230](https://github.com/singerdmx/flutter-quill/pull/2230)\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.6...v10.7.7", diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 89b553bd8..a816d0add 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.8.2 + +* Fixed minor typo in Hungarian (hu) localization by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2307 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.1...v10.8.2 + ## 10.8.1 - This release fixes the compilation issue when building the project with [Flutter/Wasm](https://docs.flutter.dev/platform-integration/web/wasm) target on the web. Also, update the conditional import check to avoid using `dart.library.html`: diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 1c0e94b5d..70046cc92 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.8.1 +version: 10.8.2 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 89b553bd8..a816d0add 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.8.2 + +* Fixed minor typo in Hungarian (hu) localization by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2307 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.1...v10.8.2 + ## 10.8.1 - This release fixes the compilation issue when building the project with [Flutter/Wasm](https://docs.flutter.dev/platform-integration/web/wasm) target on the web. Also, update the conditional import check to avoid using `dart.library.html`: diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 814a275d0..83f1960b6 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.8.1 +version: 10.8.2 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 21dd14fae..a947aab86 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.8.1 +version: 10.8.2 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 241c6fafd96fa10ad88ce6df7f2f8d3c5836782d Mon Sep 17 00:00:00 2001 From: Ellet Date: Sun, 6 Oct 2024 18:12:50 +0300 Subject: [PATCH 075/113] fix(example): build failure on Android with latest version of Android Studio Ladybug (#2312) * fix(example): build failure on Android with the latest version of Android Studio Ladybug --- example/android/app/build.gradle | 8 ++++++-- example/android/gradle.properties | 3 +++ example/android/gradle/wrapper/gradle-wrapper.properties | 4 +++- example/android/settings.gradle | 4 ++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index b8a6b7f83..41df88424 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -29,8 +29,12 @@ android { ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17 } defaultConfig { diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 3b5b324f6..5f5d39d06 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1,3 +1,6 @@ org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true +android.defaults.buildfeatures.buildconfig=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index e1ca574ef..1af9e0930 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle index 536165d35..29e2c11de 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -18,8 +18,8 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.3.0" apply false - id "org.jetbrains.kotlin.android" version "1.7.10" apply false + id "com.android.application" version '8.3.1' apply false + id "org.jetbrains.kotlin.android" version "1.8.22" apply false } include ":app" From d09e4792a62b9f26d71126842a024a836da78c32 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 17 Oct 2024 02:46:25 +0300 Subject: [PATCH 076/113] feat: Use quill_native_bridge as default impl in DefaultClipboardService, fix related bugs in the extensions package (#2230) * feat(quill_native_bridge): add initial implementation for getClipboardHTML() method channel for Android and iOS, example and Android platform directory * chore(example): use quill_native_bridge from path in dependency_overrides * feat: use quill_native_bridge for HTML Clipboard in flutter_quill and the example (initial impl) * feat(quill_native_bridge): extend the support for macOS. * chore(example): clear todos in app module build.gradle * chore(android): additional check before accessing the clip data item * fix(flutter_quill_extensions): unrelated bug for copying an image (needs further fixes) * feat: add copyImageToClipboard() method channel, an asset file in the example, and set supported platforms in pubspec.yaml, configure quill_native_bridge example * docs(readme): add an optional step to configure copying images to the clipboard on Android for quill_native_bridge * feat: use copyImageToClipboard() in flutter_quill_extensions, fix common issues in the copy image button * chore: correct name of _loadImageBytesFromImageProvider() * feat: add web support for copyImageToClipboard() * feat: (WIP) retrieving image files from the clipboard, simplifying ClipboardService, slightly updating Android, disabling copyImageToClipboard() for web (temporarily). WIP * chore(example): rename _flutterQuillAssetImage to _kFlutterQuillAssetImage * chore(example): update error messages in quill_native_bridge example * feat: add support for gif, fix unhandled exception on Android only when getting an image from the clipboard before closing the app on a new app start, clean up the platform support check * chore(example): configure the Android example for copying images to the system clipboard, update README.md * feat: support for web (WIP, will be updated soon) * chore: annotate ClipboardService and related classes as experimental * chore: temporarily add dependency_overrides to fix build failure - revert this change later * feat: separate web implementation from quill_native_bridge into quill_native_bridge_web * chore: update description of quill_native_bridge_web * chore(web): avoid using jsify() when possible * chore: publish and use quill_native_bridge_web in quill_native_bridge, update to the newly published quill_native_bridge in flutter_quill * docs(readme): use pub.dev link of quill_native_bridge in quill_native_bridge_web * chore: use .toJS in clipboardItem map (minor change) * fix: use hosted quill_native_bridge in dependencies and override with the local path in dependency_overrides * fix: update minimum required version of Flutter/Dart by quill_native_bridge * test: write basic integration tests for getClipboardImage() and copyImageToClipboard() * feat: add copyHTMLToClipboard(), add integration tests for copyHTMLToClipboard() and getClipboardHTML(), minor cleanup in the example * chore: cleanup QuillNativeBridgeWeb, extract mime constants, organize the order of implemented methods * fix(web): issue caused by previous commit * docs(web): update methods of QuillNativeBridge to reflect the web support * chore(android): cleanup the check for HTML from the clipboard in getClipboardHTML * test: add a test for getClipboardHTML to ensure it's not null only when the HTML item is the last/primary * ci: attempt to fix CI failure by updating the outdated path of quill_native_bridge after splitting the web implementation * docs: document why platform implementations of QuillNativeBridgePlatform should extend it rather than implements * chore(example): add Windows platform runner example using Flutter CLI (change is automated) * feat: (WIP) add windows experimental support for getClipboardHTML(), new integration test to ensure the HTML is parsable * fix(docs): update incorrect description of quill_native_bridge_windows in README * refactor: move plugin platform interface to quill_native_bridge_platform_interface * chore: (WIP): publish quill_native_bridge 10.7.5 * chore: (WIP) publish quill_native_bridge_web to use quill_native_bridge_platform_interface * chore(example): add Linux platform runner example using Flutter CLI (change is automated) * feat(linux): (WIP) highly experimental Linux support using xclip * fix(windows): non case sensitive check in stripWin32HtmlDescription() suggested by @AtlasAutocode * chore(example): unrelated change for windows in Flutter Quill example due to using flutter_inappwebview_windows without running the example on windows (outside of this PR) * chore(android): cleanup onMethodCall() in QuillNativeBridgePlugin * docs(readme): update docs to reflect the changes * chore: use hasWebSupport instead of hardcoding the check directly in QuillNativeBridgePlatformFeature.isSupported * feat: rename MethodChannelQuillNativeBridge.methodChannel to testMethodChannel, check in development mode to ensure that testMethodChannel can be only used in unit tests for non-web platforms * refactor: move android implementation from quill_native_bridge to quill_native_bridge_android, use pigeon for Android * chore: update QuillNativeBridgeAndroid.registerWith() assert message * refactor(apple): move iOS and macOS implementation from quill_native_bridge to quill_native_bridge_ios and quill_native_bridge_macos, use pigeon for iOS and macOS, clean the code and update QuillNativeBridge to QuillNativeBridgeImpl on Android * chore: add quill_native_bridge_platform_interface in pubspec_overides.yaml of quill_native_bridge * refactor: rename copyHTMLToClipboard() and getClipboardHTML() to copyHtmlToClipboard() and getClipboardHtml() * feat: more advanced method to check the platform support check allowing each platform to have its own check, publish a new experimental version of quill_native_version * chore(analysis): remove unused imports in quill_native_bridge and quill_native_bridge_platform_interface * fix(ci): temporarily pub get quill_native_bridge packages in main workflow * chore: format dart pigeon generated files as a workaround to CI failure * chore(deps): update flutter_lints to 5.0.0 in quill_native_bridge * refactor(windows): move CloseClipboard() to finally block in getClipboardHtml() * chore(windows): clear todo related to previous commit * chore(readme): remove description from the platform support table, use emojis instead of text for readability * chore(readme): use different emoji for platforms that don't support a feature or are inapplicable in the platform support table * style(windows): use TEXT and free from win32 instead of toNativeUtf16() and calloc.free(pointer) from ffi * refactor(windows): only register HTML format id once * feat(windows): (WIP) highly experimental support for copyHtmlToClipboard(), minor cleanup (need more) * refactor: extract supported platforms into Set for isSupported() * chore(windows): add error code in errors using GetLastError() * chore(windows): avoid passing the locked memory pointer to SetClipboardData() in copyHtmlToClipboard() * docs(readme): document android platform configuration in quill_native_bridge * fix(windows): (WIP) GlobalUnlock before SetClipboardData and GlobalFree on SetClipboardData failure * docs(readme): slightly improve platform configuration docs in quill_native_bridge * fix(windows): GlobalUnlock() the handle instead of pointer before calling GlobalUnlock() * chore(android): add reference to Flutter #63533 * chore(android): define package in GeneratedMessages.kt, update related imports * chore(android): ignore analysis warning for the generated code messages.g.dart * feat: (WIP) add initial support for getClipboardFiles() * chore(ci): format generated messages.g.dart file to bypass CI failure * feat(linux): add support for getClipboardFiles() * docs: update the old reference of QuillNativeBridgeFeature, add doc comment for the library * chore(readme): add link for quill_native_bridge, correct minor typo * chore(docs): minor changes to update the doc comment in QuillController * chore: move quill_native_bridge to https://github.com/FlutterQuill/quill-native-bridge * docs(readme): improve the 'Rich Text Paste' section, drop the TODO for providing a way to customize the paste behavior and customize the clipboard operations * chore: update deprecation message of FlutterQuillExtensions.useSuperClipboardPlugin() to reflect the change * chore(example): remove the comment of deprecated method FlutterQuillExtensions.useSuperClipboardPlugin() * chore: rename ClipboardService.copyImageToClipboard() to ClipboardService.copyImage() (non-breaking change) * chore: add a link to a TODO in DefaultClipboardService._getClipboardFile() --- .github/workflows/main.yml | 3 - README.md | 66 +- .../android/app/src/main/AndroidManifest.xml | 11 + .../app/src/main/res/xml/file_paths.xml | 3 + example/lib/main.dart | 3 - .../Flutter/GeneratedPluginRegistrant.swift | 2 + example/macos/Podfile.lock | 19 +- example/pubspec.yaml | 1 - flutter_quill_extensions/README.md | 36 +- .../lib/flutter_quill_extensions.dart | 11 +- .../lib/src/common/utils/utils.dart | 21 +- .../lib/src/editor/image/image_embed.dart | 9 +- .../lib/src/editor/image/image_menu.dart | 43 +- .../clipboard/super_clipboard_service.dart | 110 +- .../pubspec_overrides.yaml | 4 + lib/extensions.dart | 2 + lib/flutter_quill_internal.dart | 2 + lib/src/controller/quill_controller.dart | 4 +- .../quill_controller_rich_paste.dart | 18 +- .../editor/raw_editor/raw_editor_state.dart | 8 +- .../clipboard/clipboard_service.dart | 56 +- .../clipboard/clipboard_service_provider.dart | 7 +- .../clipboard/default_clipboard_service.dart | 127 +- lib/src/toolbar/buttons/clipboard_button.dart | 5 +- pubspec.yaml | 2 +- quill_native_bridge/.gitignore | 29 - quill_native_bridge/.metadata | 30 - quill_native_bridge/CHANGELOG.md | 2970 ----------------- quill_native_bridge/LICENSE | 21 - quill_native_bridge/README.md | 6 - quill_native_bridge/analysis_options.yaml | 32 - quill_native_bridge/ios/.gitignore | 38 - quill_native_bridge/ios/Assets/.gitkeep | 0 .../ios/Classes/QuillNativeBridgePlugin.swift | 23 - .../ios/quill_native_bridge.podspec | 29 - .../lib/quill_native_bridge.dart | 14 - .../quill_native_bridge_method_channel.dart | 32 - ...uill_native_bridge_platform_interface.dart | 31 - quill_native_bridge/pubspec.yaml | 27 - ...ill_native_bridge_method_channel_test.dart | 31 - .../test/quill_native_bridge_test.dart | 29 - 41 files changed, 269 insertions(+), 3646 deletions(-) create mode 100644 example/android/app/src/main/res/xml/file_paths.xml create mode 100644 flutter_quill_extensions/pubspec_overrides.yaml delete mode 100644 quill_native_bridge/.gitignore delete mode 100644 quill_native_bridge/.metadata delete mode 100644 quill_native_bridge/CHANGELOG.md delete mode 100644 quill_native_bridge/LICENSE delete mode 100644 quill_native_bridge/README.md delete mode 100644 quill_native_bridge/analysis_options.yaml delete mode 100644 quill_native_bridge/ios/.gitignore delete mode 100644 quill_native_bridge/ios/Assets/.gitkeep delete mode 100644 quill_native_bridge/ios/Classes/QuillNativeBridgePlugin.swift delete mode 100644 quill_native_bridge/ios/quill_native_bridge.podspec delete mode 100644 quill_native_bridge/lib/quill_native_bridge.dart delete mode 100644 quill_native_bridge/lib/src/quill_native_bridge_method_channel.dart delete mode 100644 quill_native_bridge/lib/src/quill_native_bridge_platform_interface.dart delete mode 100644 quill_native_bridge/pubspec.yaml delete mode 100644 quill_native_bridge/test/quill_native_bridge_method_channel_test.dart delete mode 100644 quill_native_bridge/test/quill_native_bridge_test.dart diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aefda4b23..9adb75e62 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,9 +33,6 @@ jobs: - name: 📦 Install flutter_quill_test dependencies run: flutter pub get -C flutter_quill_test - - name: 📦 Install quill_native_bridge dependencies - run: flutter pub get -C quill_native_bridge - - name: 🔍 Run Flutter analysis run: flutter analyze diff --git a/README.md b/README.md index e8e12ee71..7ac721aa7 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ You can join our [Slack Group] for discussion. - [📦 Embed Blocks](#-embed-blocks) - [🔄 Conversion to HTML](#-conversion-to-html) - [📝 Spelling checker](#-spelling-checker) +- [📝 Rich Text Paste](#-rich-text-paste) - [✂️ Shortcut events](#-shortcut-events) - [🌐 Translation](#-translation) - [🧪 Testing](#-testing) @@ -108,20 +109,57 @@ dependencies: The `flutter_quill` package uses the following plugins: -1. [`url_launcher`](https://pub.dev/packages/url_launcher) to open links. -2. [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge) to access platform-specific APIs for the +1. [`url_launcher`](https://pub.dev/packages/url_launcher): to open links. +2. [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge): to access platform-specific APIs for the editor. 3. [`flutter_keyboard_visibility_temp_fork`](https://pub.dev/packages/flutter_keyboard_visibility_temp_fork) to listen for keyboard - visibility - changes. + visibility changes. -All of them don't require any platform-specific setup. +### Android Configuration for `quill_native_bridge` + +To support copying images to the clipboard to be accessed by other apps, you need to configure your Android project. +If not set up, a warning will appear in the log during debug mode only. + +> [!TIP] +> This is only required on **Android** for this optional feature. +> You should be able to copy images and paste them inside the editor without any additional configuration. + +**1. Update `AndroidManifest.xml`** + +Open `your_project/android/app/src/main/AndroidManifest.xml` and add the following inside the `` tag: + +```xml + + + ... + + + + ... + + +``` + +**2. Create `file_paths.xml`** + +Create the file `your_project/android/app/src/main/res/xml/file_paths.xml` with the following content: + +```xml + + + +``` > [!NOTE] -> Starting from Flutter Quill `9.4.x`, [super_clipboard](https://pub.dev/packages/super_clipboard) has been moved -> to [FlutterQuill Extensions], to use rich text pasting, support pasting images, and gif files from external apps or -> websites, take a look -> at `flutter_quill_extensions` Readme. +> [super_clipboard](https://pub.dev/packages/super_clipboard) is no longer required +> in recent versions of Flutter Quill in `flutter_quill` or `flutter_quill_extensions`. +> [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge) is a plugin that provide clipboard operations functionality for `flutter_quill`. ## 🚀 Usage @@ -307,6 +345,16 @@ The following packages can be used: This feature is currently not implemented and is being planned. Refer to [#2246](https://github.com/singerdmx/flutter-quill/issues/2246) for discussion. +## 📝 Rich Text Paste + +This feature allows the user to paste the content copied from other apps into the editor as rich text. +The plugin [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge) provides access to the system Clipboard. + +> [!IMPORTANT] +> Currently this feature is not supported on the web. +> See [issue #1998](https://github.com/singerdmx/flutter-quill/issues/1998) and [issue #2220](https://github.com/singerdmx/flutter-quill/issues/2220) + for more details + ## ✂️ Shortcut events We can customize some Shorcut events, using the parameters `characterShortcutEvents` or `spaceShortcutEvents` from `QuillEditorConfigurations` to add more functionality to our editor. diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index e68e61dfa..b4ca5acfe 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -62,5 +62,16 @@ android:authorities="com.example.example.SuperClipboardDataProvider" android:exported="true" android:grantUriPermissions="true" /> + + + + + \ No newline at end of file diff --git a/example/android/app/src/main/res/xml/file_paths.xml b/example/android/app/src/main/res/xml/file_paths.xml new file mode 100644 index 000000000..11a4d5070 --- /dev/null +++ b/example/android/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index 499b11bca..27e107671 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -7,7 +7,6 @@ import 'package:flutter_localizations/flutter_localizations.dart' GlobalWidgetsLocalizations; import 'package:flutter_quill/flutter_quill.dart' show Document; import 'package:flutter_quill/translations.dart' show FlutterQuillLocalizations; -import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; import 'screens/home/widgets/home_screen.dart'; import 'screens/quill/quill_screen.dart'; @@ -20,8 +19,6 @@ import 'screens/settings/widgets/settings_screen.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - // ignore: deprecated_member_use - FlutterQuillExtensions.useSuperClipboardPlugin(); runApp(const MyApp()); } diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index bf1bbe800..988945165 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -11,6 +11,7 @@ import file_selector_macos import gal import irondash_engine_context import path_provider_foundation +import quill_native_bridge_macos import share_plus import sqflite import super_native_extensions @@ -24,6 +25,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin")) IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + QuillNativeBridgePlugin.register(with: registry.registrar(forPlugin: "QuillNativeBridgePlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin")) diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index 72d8d70f9..d9fe20ac9 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -5,19 +5,17 @@ PODS: - FlutterMacOS - file_selector_macos (0.0.1): - FlutterMacOS - - flutter_inappwebview_macos (0.0.1): - - FlutterMacOS - - OrderedSet (~> 5.0) - FlutterMacOS (1.0.0) - gal (1.0.0): - Flutter - FlutterMacOS - irondash_engine_context (0.0.1): - FlutterMacOS - - OrderedSet (5.0.0) - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS + - quill_native_bridge_macos (0.0.1): + - FlutterMacOS - share_plus (0.0.1): - FlutterMacOS - sqflite (0.0.3): @@ -35,21 +33,17 @@ DEPENDENCIES: - desktop_drop (from `Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`) - - flutter_inappwebview_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - gal (from `Flutter/ephemeral/.symlinks/plugins/gal/darwin`) - irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) + - quill_native_bridge_macos (from `Flutter/ephemeral/.symlinks/plugins/quill_native_bridge_macos/macos`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`) - super_native_extensions (from `Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - video_player_avfoundation (from `Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin`) -SPEC REPOS: - trunk: - - OrderedSet - EXTERNAL SOURCES: desktop_drop: :path: Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos @@ -57,8 +51,6 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos file_selector_macos: :path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos - flutter_inappwebview_macos: - :path: Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos FlutterMacOS: :path: Flutter/ephemeral gal: @@ -67,6 +59,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos path_provider_foundation: :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin + quill_native_bridge_macos: + :path: Flutter/ephemeral/.symlinks/plugins/quill_native_bridge_macos/macos share_plus: :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos sqflite: @@ -82,12 +76,11 @@ SPEC CHECKSUMS: desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898 device_info_plus: ce1b7762849d3ec103d0e0517299f2db7ad60720 file_selector_macos: 54fdab7caa3ac3fc43c9fac4d7d8d231277f8cf2 - flutter_inappwebview_macos: 9600c9df9fdb346aaa8933812009f8d94304203d FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 gal: 61e868295d28fe67ffa297fae6dacebf56fd53e1 irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478 - OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 + quill_native_bridge_macos: f90985c5269ac7ba84d933605b463d96e5f544fe share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3 diff --git a/example/pubspec.yaml b/example/pubspec.yaml index d87d3c7c3..5666871d5 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -59,7 +59,6 @@ dependency_overrides: flutter_quill_test: path: ../flutter_quill_test - dev_dependencies: flutter_test: sdk: flutter diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index 8a6ab3388..98988ae9d 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -50,11 +50,6 @@ The package uses the following plugins: platform-specific setup. 2. [`image_picker`](https://pub.dev/packages/image_picker) for picking images. See the [Installation](https://pub.dev/packages/image_picker#installation) section. -3. [`super_clipboard`](https://pub.dev/packages/super_clipboard) which needs some setup on Android only, it's used to - support copying images and pasting them into editor, it's also required to support rich text pasting feature on - non-web platforms, Open the [Android Support](https://pub.dev/packages/super_clipboard#android-support) page for - instructions. - The `minSdkVersion` for **Android** is `23` as `super_clipboard` requires it ### Loading Images from the Internet @@ -151,35 +146,8 @@ This works only for non-web platforms. ### 📝 Rich Text Paste Feature -The Rich Text Pasting feature requires native code to access -the `Clipboard` data as HTML, the plugin `super_clipboard` is required on all platforms except Web. - -This package already includes `super_clipboard` and will be used internally in this package, to use it -in `flutter_quill`, call this function before using any of the widgets or functionalities: - -```dart -FlutterQuillExtensions.useSuperClipboardPlugin(); -``` - -`super_clipboard` is a comprehensive plugin that provides many clipboard features for reading and writing rich text, -images and other formats. - -Calling this function will allow `flutter_quill` to use modern rich text features to paste HTML and Markdown, -support for GIF files, and other formats. - -> [!IMPORTANT] -> On web platforms, you can only get the HTML from `Clipboard` on the -> `paste` event, `super_clipboard`, or any plugin is not required. -> The paste feature will not work using the standard paste hotkey logic. -> As such, you will be unable to use the **Rich Text Paste Feature** on a button or in the web app itself. -> So you might want to either display a dialog when pressing the paste button that explains the limitation and shows the -> hotkey they need to press in order to paste or develop an extension for the browser that bypasses this limitation -> similarly to **Google Docs** and provide a link to install the browser extension. -> See [Issue #1998](https://github.com/singerdmx/flutter-quill/issues/1998) for more details. - -> [!NOTE] -> We're still planning on how this should be implemented in -> [Issue #1998](https://github.com/singerdmx/flutter-quill/issues/1998). +The rich text paste feature is now supported directly in `flutter_quill` +as platform code is not bundled with the project. ### 🖼️ Image Assets diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 3abf9314e..e36dce9e1 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -1,7 +1,7 @@ library; -// ignore: implementation_imports -import 'package:flutter_quill/src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart' + show ClipboardServiceProvider; import 'package:meta/meta.dart' show experimental; import 'src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart'; @@ -64,8 +64,11 @@ class FlutterQuillExtensions { /// to allow `flutter_quill` package to use `super_clipboard` plugin /// to support rich text features, gif and images. @Deprecated( - 'Should not be used anymore as super_clipboard will moved outside of flutter_quill_extensions soon.\n' - 'A replacement is being made in https://github.com/singerdmx/flutter-quill/pull/2230', + 'The functionality of super_clipboard is now built-in in recent versions of flutter_quill.\n' + 'To migrate, remove this function call and see ' + 'https://pub.dev/packages/quill_native_bridge#-platform-configuration (optional for copying images on Android) to use quill_native_bridge implementation (the new default).\n' + 'Or if you want to use super_clipboard implementation (support might discontinued in newer versions), use the package https://pub.dev/packages/quill_super_clipboard\n' + 'See https://github.com/singerdmx/flutter-quill/pull/2230 for more details.', ) @experimental static void useSuperClipboardPlugin() { diff --git a/flutter_quill_extensions/lib/src/common/utils/utils.dart b/flutter_quill_extensions/lib/src/common/utils/utils.dart index f8fa05f4f..7e6b6d8ca 100644 --- a/flutter_quill_extensions/lib/src/common/utils/utils.dart +++ b/flutter_quill_extensions/lib/src/common/utils/utils.dart @@ -1,8 +1,6 @@ import 'dart:io' show File; -import 'package:cross_file/cross_file.dart'; -import 'package:flutter/foundation.dart' show Uint8List, immutable; -import 'package:http/http.dart' as http; +import 'package:flutter/foundation.dart' show immutable; import '../../editor/image/widgets/image.dart'; import '../../editor_toolbar_shared/image_saver/s_image_saver.dart'; @@ -51,23 +49,6 @@ class SaveImageResult { final SaveImageResultMethod method; } -Future convertImageToUint8List(String image) async { - if (isHttpBasedUrl(image)) { - final response = await http.get(Uri.parse(image)); - if (response.statusCode == 200) { - return Uint8List.fromList(response.bodyBytes); - } - return null; - } - // TODO: Add support for all image providers like AssetImage - try { - final file = XFile(image); - return await file.readAsBytes(); - } catch (e) { - return null; - } -} - Future saveImage({ required String imageUrl, required ImageSaverService imageSaverService, diff --git a/flutter_quill_extensions/lib/src/editor/image/image_embed.dart b/flutter_quill_extensions/lib/src/editor/image/image_embed.dart index 4e41985dd..5e6985541 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_embed.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_embed.dart @@ -29,8 +29,6 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { bool inline, TextStyle textStyle, ) { - // assert(!kIsWeb, 'Please provide image EmbedBuilder for Web'); - final imageSource = standardizeImageUrl(node.value.data); final ((imageSize), margin, alignment) = getElementAttributes( node, @@ -40,7 +38,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { final width = imageSize.width; final height = imageSize.height; - final image = getImageWidgetByImageSource( + final imageWidget = getImageWidgetByImageSource( context: context, imageSource, imageProviderBuilder: configurations.imageProviderBuilder, @@ -72,6 +70,7 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { imageSize: imageSize, isReadOnly: readOnly, imageSaverService: imageSaverService, + imageProvider: imageWidget.image, ), ), ); @@ -81,10 +80,10 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder { if (margin != null) { return Padding( padding: EdgeInsets.all(margin), - child: image, + child: imageWidget, ); } - return image; + return imageWidget; }, ), ); diff --git a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart index 36e009c5c..6f64c4e5f 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart @@ -1,11 +1,13 @@ +import 'dart:async' show Completer; +import 'dart:ui' as ui; + import 'package:flutter/cupertino.dart' show showCupertinoModalPopup; -import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:flutter/foundation.dart' show kIsWeb, Uint8List; import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart' show ImageUrl, QuillController, StyleAttribute, getEmbedNode; import 'package:flutter_quill/flutter_quill_internal.dart'; import 'package:flutter_quill/translations.dart'; -import 'package:super_clipboard/super_clipboard.dart'; import '../../common/utils/element_utils/element_utils.dart'; import '../../common/utils/string.dart'; @@ -24,6 +26,7 @@ class ImageOptionsMenu extends StatelessWidget { required this.imageSize, required this.isReadOnly, required this.imageSaverService, + required this.imageProvider, super.key, }); @@ -33,6 +36,7 @@ class ImageOptionsMenu extends StatelessWidget { final ElementSize imageSize; final bool isReadOnly; final ImageSaverService imageSaverService; + final ImageProvider imageProvider; @override Widget build(BuildContext context) { @@ -87,22 +91,16 @@ class ImageOptionsMenu extends StatelessWidget { leading: const Icon(Icons.copy_all_outlined), title: Text(context.loc.copy), onTap: () async { - final navigator = Navigator.of(context); - final imageNode = - getEmbedNode(controller, controller.selection.start).value; - final image = imageNode.value.data; + Navigator.of(context).pop(); controller.copiedImageUrl = ImageUrl( - image, + imageSource, getImageStyleString(controller), ); - final data = await convertImageToUint8List(image); - final clipboard = SystemClipboard.instance; - if (data != null) { - final item = DataWriterItem()..add(Formats.png(data)); - await clipboard?.write([item]); + final imageBytes = await _loadImageBytesFromImageProvider(); + if (imageBytes != null) { + await ClipboardServiceProvider.instance.copyImage(imageBytes); } - navigator.pop(); }, ), if (!isReadOnly) @@ -199,4 +197,23 @@ class ImageOptionsMenu extends StatelessWidget { ), ); } + + // TODO: This will load the image again, in case it was network image + // then it will send a GET request each time to load the image. + Future _loadImageBytesFromImageProvider() async { + final stream = imageProvider.resolve(ImageConfiguration.empty); + final completer = Completer(); + + ImageStreamListener? listener; + listener = ImageStreamListener((info, _) { + completer.complete(info.image); + stream.removeListener(listener!); + }); + + stream.addListener(listener); + + final image = await completer.future; + final byteData = await image.toByteData(format: ui.ImageByteFormat.png); + return byteData?.buffer.asUint8List(); + } } diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart b/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart index cd83b410e..51466ff61 100644 --- a/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart +++ b/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart @@ -2,14 +2,16 @@ import 'dart:async' show Completer; import 'dart:convert' show utf8; import 'package:flutter/foundation.dart'; -// ignore: implementation_imports -import 'package:flutter_quill/src/editor_toolbar_controller_shared/clipboard/clipboard_service.dart'; +import 'package:flutter_quill/flutter_quill_internal.dart' + show ClipboardService; +import 'package:meta/meta.dart' show experimental; import 'package:super_clipboard/super_clipboard.dart'; -/// Implementation based on https://pub.dev/packages/super_clipboard -class SuperClipboardService implements ClipboardService { - /// Null if the Clipboard API is not supported on this platform +/// Implementation using the https://pub.dev/packages/super_clipboard plugin. +@experimental +class SuperClipboardService extends ClipboardService { + /// [Null] if the Clipboard API is not supported on this platform /// https://pub.dev/packages/super_clipboard#usage SystemClipboard? _getSuperClipboard() { return SystemClipboard.instance; @@ -74,99 +76,63 @@ class SuperClipboardService implements ClipboardService { } @override - Future canProvideHtmlText() { - return _canProvide(format: Formats.htmlText); - } - - @override - Future getHtmlText() { + Future getHtmlText() async { + if (!(await _canProvide(format: Formats.htmlText))) { + return null; + } return _provideSimpleValueFormatAsString(format: Formats.htmlText); } @override - Future canProvideHtmlTextFromFile() { - return _canProvide(format: Formats.htmlFile); - } - - @override - Future getHtmlTextFromFile() { - return _provideFileAsString(format: Formats.htmlFile); - } - - @override - Future canProvideMarkdownText() async { - // Formats.markdownText or Formats.mdText does not exist yet in super_clipboard - return false; - } - - @override - Future getMarkdownText() async { - // Formats.markdownText or Formats.mdText does not exist yet in super_clipboard - throw UnsupportedError( - 'SuperClipboardService does not support retrieving image files.', - ); - } - - @override - Future canProvideMarkdownTextFromFile() async { - // Formats.md is for markdown files - return _canProvide(format: Formats.md); - } - - @override - Future getMarkdownTextFromFile() async { - // Formats.md is for markdown files - return _provideFileAsString(format: Formats.md); - } - - @override - Future canProvidePlainText() { - return _canProvide(format: Formats.plainText); + Future getHtmlFile() async { + if (!(await _canProvide(format: Formats.htmlFile))) { + return null; + } + return await _provideFileAsString(format: Formats.htmlFile); } @override - Future getPlainText() { - return _provideSimpleValueFormatAsString(format: Formats.plainText); + Future getGifFile() async { + if (!(await _canProvide(format: Formats.gif))) { + return null; + } + return await _provideFileAsBytes(format: Formats.gif); } - /// This will need to be updated if [getImageFileAsBytes] updated. - /// Notice that even if the copied image is JPEG, it still can be provided - /// as PNG, will handle JPEG check in case this info is incorrect. @override - Future canProvideImageFile() async { + Future getImageFile() async { final canProvidePngFile = await _canProvide(format: Formats.png); if (canProvidePngFile) { - return true; + return _provideFileAsBytes(format: Formats.png); } final canProvideJpegFile = await _canProvide(format: Formats.jpeg); if (canProvideJpegFile) { - return true; + return _provideFileAsBytes(format: Formats.jpeg); } - return false; + return null; } - /// This will need to be updated if [canProvideImageFile] updated. @override - Future getImageFileAsBytes() async { - final canProvidePngFile = await _canProvide(format: Formats.png); - if (canProvidePngFile) { - return _provideFileAsBytes(format: Formats.png); + Future getMarkdownFile() async { + // Formats.md is for markdown files + if (!(await _canProvide(format: Formats.md))) { + return null; } - return _provideFileAsBytes(format: Formats.jpeg); + return await _provideFileAsString(format: Formats.md); } @override - Future canProvideGifFile() { - return _canProvide(format: Formats.gif); - } - - @override - Future getGifFileAsBytes() { - return _provideFileAsBytes(format: Formats.gif); + Future copyImage(Uint8List imageBytes) async { + final clipboard = SystemClipboard.instance; + if (clipboard == null) { + return; + } + final item = DataWriterItem()..add(Formats.png(imageBytes)); + await clipboard.write([item]); } @override - Future canPaste() async { + Future get hasClipboardContent async { final clipboard = _getSuperClipboard(); if (clipboard == null) { return false; diff --git a/flutter_quill_extensions/pubspec_overrides.yaml b/flutter_quill_extensions/pubspec_overrides.yaml new file mode 100644 index 000000000..b4f64788e --- /dev/null +++ b/flutter_quill_extensions/pubspec_overrides.yaml @@ -0,0 +1,4 @@ +# TODO: Remove this file completely once https://github.com/singerdmx/flutter-quill/pull/2230 is complete before publishing +dependency_overrides: + flutter_quill: + path: ../ \ No newline at end of file diff --git a/lib/extensions.dart b/lib/extensions.dart index 9ce60ebf1..9b5596b03 100644 --- a/lib/extensions.dart +++ b/lib/extensions.dart @@ -13,6 +13,8 @@ export 'src/common/utils/platform.dart'; export 'src/common/utils/string.dart'; export 'src/common/utils/widgets.dart'; export 'src/document/nodes/leaf.dart'; +export 'src/editor_toolbar_controller_shared/clipboard/clipboard_service.dart'; +export 'src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; export 'src/rules/delete.dart'; export 'src/rules/format.dart'; export 'src/rules/insert.dart'; diff --git a/lib/flutter_quill_internal.dart b/lib/flutter_quill_internal.dart index 215778ee1..50d2fde78 100644 --- a/lib/flutter_quill_internal.dart +++ b/lib/flutter_quill_internal.dart @@ -15,6 +15,8 @@ export 'src/common/utils/platform.dart'; export 'src/common/utils/string.dart'; export 'src/common/utils/widgets.dart'; export 'src/document/nodes/leaf.dart'; +export 'src/editor_toolbar_controller_shared/clipboard/clipboard_service.dart'; +export 'src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; export 'src/rules/delete.dart'; export 'src/rules/format.dart'; export 'src/rules/insert.dart'; diff --git a/lib/src/controller/quill_controller.dart b/lib/src/controller/quill_controller.dart index 97a6a5391..2ffdcb049 100644 --- a/lib/src/controller/quill_controller.dart +++ b/lib/src/controller/quill_controller.dart @@ -551,7 +551,7 @@ class QuillController extends ChangeNotifier { } /// Returns whether paste operation was handled here. - /// updateEditor is called if paste operation was successful. + /// [updateEditor] is called if paste operation was successful. Future clipboardPaste({void Function()? updateEditor}) async { if (readOnly || !selection.isValid) return true; @@ -612,7 +612,7 @@ class QuillController extends ChangeNotifier { return false; } - /// Return true if can paste internal image + /// Return `true` if can paste internal image Future _pasteInternalImage() async { final copiedImageUrl = _copiedImageUrl; if (copiedImageUrl != null) { diff --git a/lib/src/controller/quill_controller_rich_paste.dart b/lib/src/controller/quill_controller_rich_paste.dart index ed1ca318c..486516bed 100644 --- a/lib/src/controller/quill_controller_rich_paste.dart +++ b/lib/src/controller/quill_controller_rich_paste.dart @@ -24,11 +24,13 @@ extension QuillControllerRichPaste on QuillController { if (html != null) { return html; } - if (await clipboardService.canProvideHtmlTextFromFile()) { - return await clipboardService.getHtmlTextFromFile(); + final clipboardHtmlText = await clipboardService.getHtmlText(); + if (clipboardHtmlText != null) { + return clipboardHtmlText; } - if (await clipboardService.canProvideHtmlText()) { - return await clipboardService.getHtmlText(); + final clipboardHtmlFile = await clipboardService.getHtmlFile(); + if (clipboardHtmlFile != null) { + return clipboardHtmlFile; } return null; } @@ -61,11 +63,9 @@ extension QuillControllerRichPaste on QuillController { if (markdown != null) { return markdown; } - if (await clipboardService.canProvideMarkdownTextFromFile()) { - return await clipboardService.getMarkdownTextFromFile(); - } - if (await clipboardService.canProvideMarkdownText()) { - return await clipboardService.getMarkdownText(); + final clipboardMarkdownFile = await clipboardService.getMarkdownFile(); + if (clipboardMarkdownFile != null) { + return clipboardMarkdownFile; } return null; } diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index b2c0d044e..b7e3d57e0 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -153,8 +153,8 @@ class QuillRawEditorState extends EditorState final onImagePaste = widget.configurations.onImagePaste; if (onImagePaste != null) { - if (await clipboardService.canProvideImageFile()) { - final imageBytes = await clipboardService.getImageFileAsBytes(); + final imageBytes = await clipboardService.getImageFile(); + if (imageBytes != null) { final imageUrl = await onImagePaste(imageBytes); if (imageUrl == null) { return; @@ -171,8 +171,8 @@ class QuillRawEditorState extends EditorState final onGifPaste = widget.configurations.onGifPaste; if (onGifPaste != null) { - if (await clipboardService.canProvideGifFile()) { - final gifBytes = await clipboardService.getGifFileAsBytes(); + final gifBytes = await clipboardService.getGifFile(); + if (gifBytes != null) { final gifUrl = await onGifPaste(gifBytes); if (gifUrl == null) { return; diff --git a/lib/src/editor_toolbar_controller_shared/clipboard/clipboard_service.dart b/lib/src/editor_toolbar_controller_shared/clipboard/clipboard_service.dart index 848821f52..46e6c3733 100644 --- a/lib/src/editor_toolbar_controller_shared/clipboard/clipboard_service.dart +++ b/lib/src/editor_toolbar_controller_shared/clipboard/clipboard_service.dart @@ -1,44 +1,32 @@ -import 'package:flutter/foundation.dart'; +import 'package:flutter/foundation.dart' show Uint8List; +import 'package:flutter/services.dart' show Clipboard; +import 'package:meta/meta.dart' show experimental; -/// An abstraction to make it easy to provide different implementations -@immutable +/// A more rich abstraction of Flutter [Clipboard] to support images, rich text +/// and more clipboard operations. +@experimental abstract class ClipboardService { - Future canProvideHtmlText(); - - /// Get Clipboard content as Html Text, this is platform specific and not the - /// same as [getPlainText] for two reasons: - /// 1. The user might want to paste Html text - /// 2. Copying Html text from other apps and use [getPlainText] will ignore - /// the Html content and provide it as text + /// Return HTML from the Clipboard. Future getHtmlText(); - Future canProvideHtmlTextFromFile(); - - /// Get the Html file in the Clipboard from the system - Future getHtmlTextFromFile(); - - Future canProvideMarkdownText(); - - /// Get Clipboard content as Markdown Text, this is platform specific and not the - /// same as [getPlainText] for two reasons: - /// 1. The user might want to paste Markdown text - /// 2. Copying Markdown text from other apps and use [getPlainText] will ignore - /// the Markdown content and provide it as text - Future getMarkdownText(); - - Future canProvideMarkdownTextFromFile(); + /// Return HTML text file from the Clipboard. + Future getHtmlFile(); - /// Get the Markdown file in the Clipboard from the system - Future getMarkdownTextFromFile(); + /// Return the Markdown file in the Clipboard. + Future getMarkdownFile(); - Future canProvidePlainText(); - Future getPlainText(); + /// Return image from the Clipboard. + Future getImageFile(); - Future canProvideImageFile(); - Future getImageFileAsBytes(); + /// Return Gif from the Clipboard. + Future getGifFile(); - Future canProvideGifFile(); - Future getGifFileAsBytes(); + /// Copy an image to the system clipboard to paste it on other apps. + Future copyImage(Uint8List imageBytes); - Future canPaste(); + /// If the Clipboard is not empty or has something to paste + Future get hasClipboardContent async { + final clipboardData = await Clipboard.getData(Clipboard.kTextPlain); + return clipboardData != null; + } } diff --git a/lib/src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart b/lib/src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart index f90a7a9d2..aa7b9c402 100644 --- a/lib/src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart +++ b/lib/src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart @@ -1,10 +1,11 @@ -import 'package:flutter/foundation.dart' show immutable; +import 'package:meta/meta.dart' show experimental; + import 'clipboard_service.dart'; import 'default_clipboard_service.dart'; -@immutable +@experimental class ClipboardServiceProvider { - const ClipboardServiceProvider._(); + ClipboardServiceProvider._(); static ClipboardService _instance = DefaultClipboardService(); static ClipboardService get instance => _instance; diff --git a/lib/src/editor_toolbar_controller_shared/clipboard/default_clipboard_service.dart b/lib/src/editor_toolbar_controller_shared/clipboard/default_clipboard_service.dart index 4509c1100..21db10cdd 100644 --- a/lib/src/editor_toolbar_controller_shared/clipboard/default_clipboard_service.dart +++ b/lib/src/editor_toolbar_controller_shared/clipboard/default_clipboard_service.dart @@ -1,96 +1,79 @@ -import 'package:flutter/services.dart' show Clipboard, Uint8List; +import 'dart:io' as io; -import 'clipboard_service.dart'; - -/// Default implementation using only internal flutter plugins -class DefaultClipboardService implements ClipboardService { - @override - Future canProvideHtmlText() async { - return false; - } - - @override - Future getHtmlText() { - throw UnsupportedError( - 'DefaultClipboardService does not support retrieving HTML text.', - ); - } +import 'package:flutter/foundation.dart'; +import 'package:meta/meta.dart' show experimental; +import 'package:quill_native_bridge/quill_native_bridge.dart' + show QuillNativeBridge, QuillNativeBridgeFeature; - @override - Future canProvideHtmlTextFromFile() async { - return false; - } - - @override - Future getHtmlTextFromFile() { - throw UnsupportedError( - 'DefaultClipboardService does not support retrieving HTML files.', - ); - } - - @override - Future canProvideMarkdownText() async { - return false; - } - - @override - Future getMarkdownText() { - throw UnsupportedError( - 'DefaultClipboardService does not support retrieving HTML files.', - ); - } - - @override - Future canProvideMarkdownTextFromFile() async { - return false; - } +import 'clipboard_service.dart'; +/// Default implementation of [ClipboardService] to support rich clipboard +/// operations. +@experimental +class DefaultClipboardService extends ClipboardService { @override - Future getMarkdownTextFromFile() { - throw UnsupportedError( - 'DefaultClipboardService does not support retrieving Markdown text.', - ); + Future getHtmlText() async { + if (!(await QuillNativeBridge.isSupported( + QuillNativeBridgeFeature.getClipboardHtml))) { + return null; + } + return await QuillNativeBridge.getClipboardHtml(); } @override - Future canProvidePlainText() async { - final plainText = (await Clipboard.getData(Clipboard.kTextPlain))?.text; - return plainText == null; + Future getImageFile() async { + if (!(await QuillNativeBridge.isSupported( + QuillNativeBridgeFeature.getClipboardImage))) { + return null; + } + return await QuillNativeBridge.getClipboardImage(); } @override - Future getPlainText() async { - final plainText = (await Clipboard.getData(Clipboard.kTextPlain))?.text; - return plainText; + Future copyImage(Uint8List imageBytes) async { + if (!(await QuillNativeBridge.isSupported( + QuillNativeBridgeFeature.copyImageToClipboard))) { + return; + } + await QuillNativeBridge.copyImageToClipboard(imageBytes); } @override - Future canProvideImageFile() async { - return false; + Future getGifFile() async { + if (!(await QuillNativeBridge.isSupported( + QuillNativeBridgeFeature.getClipboardGif))) { + return null; + } + return QuillNativeBridge.getClipboardGif(); } - @override - Future getImageFileAsBytes() { - throw UnsupportedError( - 'DefaultClipboardService does not support retrieving image files.', + Future _getClipboardFile({required String fileExtension}) async { + if (kIsWeb) { + // TODO: Can't read file with dart:io on the Web (See related https://github.com/FlutterQuill/quill-native-bridge/issues/6) + return null; + } + final filePaths = await QuillNativeBridge.getClipboardFiles(); + final filePath = filePaths.firstWhere( + (filePath) => filePath.endsWith('.$fileExtension'), + orElse: () => '', ); + if (filePath.isEmpty) { + // Could not find an item + return null; + } + final fileText = await io.File(filePath).readAsString(); + return fileText; } @override - Future canProvideGifFile() async { - return false; - } - - @override - Future getGifFileAsBytes() { - throw UnsupportedError( - 'DefaultClipboardService does not support retrieving GIF files.', - ); + Future getHtmlFile() async { + final htmlFileText = await _getClipboardFile(fileExtension: 'html'); + return htmlFileText; } @override - Future canPaste() async { - final plainText = await getPlainText(); - return plainText != null; + Future getMarkdownFile() async { + final htmlFileText = await _getClipboardFile(fileExtension: 'md'); + return htmlFileText; } } diff --git a/lib/src/toolbar/buttons/clipboard_button.dart b/lib/src/toolbar/buttons/clipboard_button.dart index b66ffbb62..4f1d43bea 100644 --- a/lib/src/toolbar/buttons/clipboard_button.dart +++ b/lib/src/toolbar/buttons/clipboard_button.dart @@ -3,11 +3,12 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../../../flutter_quill.dart'; import '../../common/utils/widgets.dart'; import '../../editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; import '../../l10n/extensions/localizations_ext.dart'; import '../base_button/base_value_button.dart'; +import '../base_toolbar.dart'; +import '../simple_toolbar_provider.dart'; enum ClipboardAction { cut, copy, paste } @@ -28,7 +29,7 @@ class ClipboardMonitor { Future _update(void Function() listener) async { final clipboardService = ClipboardServiceProvider.instance; - if (await clipboardService.canPaste()) { + if (await clipboardService.hasClipboardContent) { _canPaste = true; listener(); } diff --git a/pubspec.yaml b/pubspec.yaml index a947aab86..98a900959 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,7 +61,7 @@ dependencies: # Plugins url_launcher: ^6.2.4 flutter_keyboard_visibility_temp_fork: ^0.1.1 - quill_native_bridge: '>=10.5.14 <=10.6.2' + quill_native_bridge: ^10.7.8 dev_dependencies: flutter_lints: ^5.0.0 diff --git a/quill_native_bridge/.gitignore b/quill_native_bridge/.gitignore deleted file mode 100644 index ac5aa9893..000000000 --- a/quill_native_bridge/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ -migrate_working_dir/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. -/pubspec.lock -**/doc/api/ -.dart_tool/ -build/ diff --git a/quill_native_bridge/.metadata b/quill_native_bridge/.metadata deleted file mode 100644 index 5d0b67954..000000000 --- a/quill_native_bridge/.metadata +++ /dev/null @@ -1,30 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: "5874a72aa4c779a02553007c47dacbefba2374dc" - channel: "stable" - -project_type: plugin - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: 5874a72aa4c779a02553007c47dacbefba2374dc - base_revision: 5874a72aa4c779a02553007c47dacbefba2374dc - - platform: ios - create_revision: 5874a72aa4c779a02553007c47dacbefba2374dc - base_revision: 5874a72aa4c779a02553007c47dacbefba2374dc - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/quill_native_bridge/CHANGELOG.md b/quill_native_bridge/CHANGELOG.md deleted file mode 100644 index f29609c4b..000000000 --- a/quill_native_bridge/CHANGELOG.md +++ /dev/null @@ -1,2970 +0,0 @@ - - -# Changelog - -All notable changes to this project will be documented in this file. - -## 10.7.3 - -- Deprecate `FlutterQuillExtensions` in `flutter_quill_extensions` -- Update the minimum version of `flutter_quill` and `super_clipboard` in `flutter_quill_extensions` to avoid using deprecated code. - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.2...v10.7.3 - -## 10.7.2 - -## What's Changed -* chore: deprecate flutter_quill/extensions.dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2258 - -This is a minor release introduced to upload a new version of `flutter_quill` and `flutter_quill_extensions` to update the minimum required to avoid using deprecated code in `flutter_quill_extensions`. - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.1...v10.7.2 - -## 10.7.1 - -* chore: deprecate markdown_quill export, ignore warnings by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2256 -* chore: deprecate spell checker service by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2255 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.0...v10.7.1 - -## 10.7.0 - -* Chore: deprecate embed table feature by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2254 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.6...v10.7.0 - -## 10.6.6 - -* Bug fix: Removing check not allowing spell check on web by @joeserhtf in https://github.com/singerdmx/flutter-quill/pull/2252 - -## New Contributors -* @joeserhtf made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2252 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.5...v10.6.6 - -## 10.6.5 - -* Refine IME composing range styling by applying underline as text style by @agata in https://github.com/singerdmx/flutter-quill/pull/2244 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.4...v10.6.5 - -## 10.6.4 - -* fix: the composing text did not show an underline during IME conversion by @agata in https://github.com/singerdmx/flutter-quill/pull/2242 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.3...v10.6.4 - -## 10.6.3 - -* Fix: Resolved issue with broken IME composing rect in Windows desktop by @agata in https://github.com/singerdmx/flutter-quill/pull/2239 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.2...v10.6.3 - -## 10.6.2 - -* Fix: QuillToolbarToggleStyleButton Switching failure by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2234 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.1...v10.6.2 - -## 10.6.1 - -* Chore: update `flutter_quill_delta_from_html` to remove exception calls by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2232 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.6.0...v10.6.1 - -## 10.6.0 - -* docs: cleanup the docs, remove outdated resources, general changes by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2227 -* Feat: customizable character and space shortcut events by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2228 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.19...v10.6.0 - -## 10.5.19 - -* fix: properties other than 'style' for custom inline code styles (such as 'backgroundColor') were not being applied correctly by @agata in https://github.com/singerdmx/flutter-quill/pull/2226 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.18...v10.5.19 - -## 10.5.18 - -* feat(web): rich text paste from Clipboard using HTML by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2009 -* revert: disable rich text paste feature on web as a workaround by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2221 -* refactor: moved shortcuts and onKeyEvents to its own file by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2223 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.17...v10.5.18 - -## 10.5.17 - -* feat(l10n): localize all untranslated.json by @erdnx in https://github.com/singerdmx/flutter-quill/pull/2217 -* Fix: Block Attributes are not displayed if the editor is empty by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2210 - -## New Contributors -* @erdnx made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2217 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.16...v10.5.17 - -## 10.5.16 - -* chore: remove device_info_plus and add quill_native_bridge to access platform specific APIs by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2194 -* Not show/update/hiden mangnifier when manifier config is disbale by @demoYang in https://github.com/singerdmx/flutter-quill/pull/2212 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.14...v10.5.16 - -## 10.5.15-dev.0 - -Introduce `quill_native_bridge` which is an internal plugin to use by `flutter_quill` to access platform APIs. - -For now, the only functionality it supports is to check whatever the iOS app is running on iOS simulator without requiring [`device_info_plus`](pub.dev/packages/device_info_plus) as a dependency. - -> [!NOTE] -> `quill_native_bridge` is a plugin for internal use and should not be used in production applications -> as breaking changes can happen and can removed at any time. - -For more details and discussion see [#2194](https://github.com/singerdmx/flutter-quill/pull/2194). - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.14...v10.5.15-dev.0 - -## 10.5.14 - -* chore(localization): add Greek language support by @DKalathas in https://github.com/singerdmx/flutter-quill/pull/2206 - -## New Contributors -* @DKalathas made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2206 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.13...v10.5.14 - -## 10.5.13 - -* Revert "Fix: Allow backspace at start of document to remove block style and header style by @agata in https://github.com/singerdmx/flutter-quill/pull/2201 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.12...v10.5.13 - -## 10.5.12 - -* Fix: Backspace remove block attributes at start by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2200 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.11...v10.5.12 - -## 10.5.11 - -* Enhancement: Backspace handling at the start of blocks in delete rules by @agata in https://github.com/singerdmx/flutter-quill/pull/2199 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.10...v10.5.11 - -## 10.5.10 - -* Allow backspace at start of document to remove block style and header style by @agata in https://github.com/singerdmx/flutter-quill/pull/2198 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.9...v10.5.10 - -## 10.5.9 - -* chore: improve platform check by using constants and defaultTargetPlatform by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2188 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.8...v10.5.9 - -## 10.5.8 - -* Feat: Add configuration option to always indent on TAB key press by @agata in https://github.com/singerdmx/flutter-quill/pull/2187 - -## New Contributors -* @agata made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2187 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.7...v10.5.8 - -## 10.5.7 - -* chore(example): downgrade Kotlin from 1.9.24 to 1.7.10 by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2185 -* style: refactor build leading function style, width, and padding parameters for custom node leading builder by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2182 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.6...v10.5.7 - -## 10.5.6 - -* chore(deps): update super_clipboard to 0.8.20 in flutter_quill_extensions by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2181 -* Update quill_screen.dart, i chaged the logic for showing a lock when … by @rightpossible in https://github.com/singerdmx/flutter-quill/pull/2183 - -## New Contributors -* @rightpossible made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2183 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.5...v10.5.6 - -## 10.5.5 - -* Fix text selection handles when scroll mobile by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2176 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.4...v10.5.5 - -## 10.5.4 - -* Add Thai (th) localization by @silkyland in https://github.com/singerdmx/flutter-quill/pull/2175 - -## New Contributors -* @silkyland made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2175 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.3...v10.5.4 - -## 10.5.3 - -* Fix: Assertion Failure in line.dart When Editing Text with Block-Level Attributes by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2174 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.2...v10.5.3 - -## 10.5.2 - -* fix(toolbar): regard showDividers in simple toolbar by @realth000 in https://github.com/singerdmx/flutter-quill/pull/2172 - -## New Contributors -* @realth000 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2172 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.1...v10.5.2 - -## 10.5.1 - -* fix drag selection extension (does not start at tap location if you are dragging quickly by @jezell in https://github.com/singerdmx/flutter-quill/pull/2170 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.5.0...v10.5.1 - -## 10.5.0 - -* Feat: custom leading builder by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2146 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.9...v10.5.0 - -## 10.4.9 - -* fix floating cursor not disappearing after scroll end by @vishna in https://github.com/singerdmx/flutter-quill/pull/2163 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.8...v10.4.9 - -## 10.4.8 - -* Fix: direction has no opposite effect if the language is rtl by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2154 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.7...v10.4.8 - -## 10.4.7 - -* Fix: Unable to scroll 2nd editor window by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2152 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.6...v10.4.7 - -## 10.4.6 - -* Handle null child query by @jezell in https://github.com/singerdmx/flutter-quill/pull/2151 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.5...v10.4.6 - -## 10.4.5 - -* chore!: move spell checker to example by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2145 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.4...v10.4.5 - -## 10.4.4 - -* fix custom recognizer builder not being passed to editabletextblock by @jezell in https://github.com/singerdmx/flutter-quill/pull/2143 -* fix null reference exception when dragging selection on non scrollable selection by @jezell in https://github.com/singerdmx/flutter-quill/pull/2144 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.3...v10.4.4 - -## 10.4.3 - -* Chore: update simple_spell_checker package by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2139 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.2...v10.4.3 - -## 10.4.2 - -* Revert "fix: Double click to select text sometimes doesn't work. ([#2086](https://github.com/singerdmx/flutter-quill/pull/2086)) - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.1...v10.4.2 - -## 10.4.1 - -* Chore: improve Spell checker API to the example by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2133 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.4.0...v10.4.1 - -## 10.4.0 - -* Copy TapAndPanGestureRecognizer from TextField by @demoYang in https://github.com/singerdmx/flutter-quill/pull/2128 -* enhance stringToColor with a custom defined palette from `DefaultStyles` by @vishna in https://github.com/singerdmx/flutter-quill/pull/2095 -* Feat: include spell checker for example app by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2127 - -## New Contributors -* @vishna made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2095 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.3.3...v10.4.0 - -## 10.3.2 - -* Fix: Loss of style when backspace by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2125 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.3.1...v10.3.2 - -## 10.3.1 - -* Chore: Move spellchecker service to extensions by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2120 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.3.0...v10.3.1 - -## 10.3.0 - -* Feat: Spellchecker for Flutter Quill by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2118 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.2.1...v10.3.0 - -## 10.2.1 - -* Fix: context menu is visible even when selection is collapsed by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2116 -* Fix: unsafe operation while getting overlayEntry in text_selection by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2117 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.2.0...v10.2.1 - -## 10.2.0 - -* refactor!: restructure project into modular architecture for flutter_quill_extensions by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2106 -* Fix: Link selection and editing by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2114 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.10...v10.2.0 - -## 10.1.10 - -* Fix(example): image_cropper outdated version by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2100 -* Using dart.library.js_interop instead of dart.library.html by @h1376h in https://github.com/singerdmx/flutter-quill/pull/2103 - -## New Contributors -* @h1376h made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2103 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.9...v10.1.10 - -## 10.1.9 - -* restore ability to pass in key to QuillEditor by @mtallenca in https://github.com/singerdmx/flutter-quill/pull/2093 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.8...v10.1.9 - -## 10.1.8 - -* Enhancement: Search within Embed objects by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2090 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.7...v10.1.8 - -## 10.1.7 - -* Feature/allow shortcut override by @InstrinsicAutomations in https://github.com/singerdmx/flutter-quill/pull/2089 - -## New Contributors -* @InstrinsicAutomations made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2089 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.6...v10.1.7 - -## 10.1.6 - -* fixed #1295 Double click to select text sometimes doesn't work. by @li8607 in https://github.com/singerdmx/flutter-quill/pull/2086 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.5...v10.1.6 - -## 10.1.5 - -* ref: add `VerticalSpacing.zero` and `HorizontalSpacing.zero` named constants by @adil192 in https://github.com/singerdmx/flutter-quill/pull/2083 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.4...v10.1.5 - -## 10.1.4 - -* Fix: collectStyles for lists and alignments by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2082 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.3...v10.1.4 - -## 10.1.3 - -* Move Controller outside of configurations data class by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2078 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.2...v10.1.3 - -## 10.1.2 - -* Fix Multiline paste with attributes and embeds by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2074 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.1...v10.1.2 - -## 10.1.1 - -* Toolbar dividers fixes + Docs updates by @troyanskiy in https://github.com/singerdmx/flutter-quill/pull/2071 - -## New Contributors -* @troyanskiy made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2071 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.1.0...v10.1.1 - -## 10.1.0 - -* Feat: support for customize copy and cut Embeddables to Clipboard by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2067 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.10...v10.1.0 - -## 10.0.10 - -* fix: Hide selection toolbar if editor loses focus by @huandu in https://github.com/singerdmx/flutter-quill/pull/2066 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.9...v10.0.10 - -## 10.0.9 - -* Fix: manual checking of directionality by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2063 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.8...v10.0.9 - -## 10.0.8 - -* feat: add callback to handle performAction by @huandu in https://github.com/singerdmx/flutter-quill/pull/2061 -* fix: Invalid selection when tapping placeholder text by @huandu in https://github.com/singerdmx/flutter-quill/pull/2062 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.7...v10.0.8 - -## 10.0.7 - -* Fix: RTL issues by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2060 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.6...v10.0.7 - -## 10.0.6 - -* fix: textInputAction is not set when creating QuillRawEditorConfiguration by @huandu in https://github.com/singerdmx/flutter-quill/pull/2057 - -## New Contributors -* @huandu made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2057 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.5...v10.0.6 - -## 10.0.5 - -* Add tests for PreserveInlineStylesRule and fix link editing. Other minor fixes. by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2058 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.4...v10.0.5 - -## 10.0.4 - -* Add ability to set up horizontal spacing for block style by @dimkanovikov in https://github.com/singerdmx/flutter-quill/pull/2051 -* add catalan language by @spilioio in https://github.com/singerdmx/flutter-quill/pull/2054 - -## New Contributors -* @dimkanovikov made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2051 -* @spilioio made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2054 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.3...v10.0.4 - -## 10.0.3 - -* doc(Delta): more documentation about Delta by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2042 -* doc(attribute): added documentation about Attribute class and how create one by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2048 -* if magnifier removes toolbar, restore it when it is hidden by @mtallenca in https://github.com/singerdmx/flutter-quill/pull/2049 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.2...v10.0.3 - -## 10.0.2 - -* chore(scripts): migrate the scripts from sh to dart by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2036 -* Have the ability to create custom rules, closes #1162 by @Guillergood in https://github.com/singerdmx/flutter-quill/pull/2040 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.1...v10.0.2 - -## 10.0.1 - -This release is identical to [10.0.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.0.0) with a fix that addresses issue #2034 by requiring `10.0.0` as the minimum version for quill related dependencies. - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.0.0...v10.0.1 - -## 10.0.0 - -* refactor: restructure project into modular architecture for flutter_quill by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2032 -* chore: update GitHub PR template by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2033 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.6.0...v10.0.0 - -## 9.6.0 - -* [feature] : quill add magnifier by @demoYang in https://github.com/singerdmx/flutter-quill/pull/2026 - -## New Contributors -* @demoYang made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2026 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.23...v9.6.0 - -## 9.5.23 - -* add untranslated Kurdish keys by @Xoshbin in https://github.com/singerdmx/flutter-quill/pull/2029 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.22...v9.5.23 - -## 9.5.22 - -* Fix outdated contributor guide link on PR template by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2027 -* Fix(rule): PreserveInlineStyleRule assume the type of the operation data and throw stacktrace by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2028 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.21...v9.5.22 - -## 9.5.21 - -* Fix: Key actions not being handled by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/2025 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.20...v9.5.21 - -## 9.5.20 - -* Remove useless delta_x_test by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2017 -* Update flutter_quill_delta_from_html package on pubspec.yaml by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2018 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.19...v9.5.20 - -## 9.5.19 - -* fixed #1835 Embed Reloads on Cmd Key Press by @li8607 in https://github.com/singerdmx/flutter-quill/pull/2013 - -## New Contributors -* @li8607 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/2013 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.18...v9.5.19 - -## 9.5.18 - -* Refactor: Moved core link button functions to link.dart by @Alspb in https://github.com/singerdmx/flutter-quill/pull/2008 -* doc: more documentation about Rules by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2014 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.17...v9.5.18 - -## 9.5.17 - -* Feat(config): added option to disable automatic list conversion by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2011 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.16...v9.5.17 - -## 9.5.16 - -* chore: drop support for HTML, PDF, and Markdown converting functions by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/1997 -* docs(readme): update the extensions package to document the Rich Text Paste feature on web by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2001 -* Fix(test): delta_x tests fail by wrong expected Delta for video embed by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2010 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.15...v9.5.16 - -## 9.5.15 - -* Update delta_from_html to fix nested lists issues and more by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/2000 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.14...v9.5.15 - -## 9.5.14 - -* docs(readme): update 'Conversion to HTML' section to include more details by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/1996 -* Update flutter_quill_delta_from_html on pubspec.yaml to fix current issues by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1999 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.13...v9.5.14 - -## 9.5.13 - -* Added new default ConverterOptions configurations by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1990 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.12...v9.5.13 - -## 9.5.12 - -* fix: Fixed passing textStyle to formula embed by @shubham030 in https://github.com/singerdmx/flutter-quill/pull/1989 - -## New Contributors -* @shubham030 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1989 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.11...v9.5.12 - -## 9.5.11 - -* Update flutter_quill_delta_from_html in pubspec.yaml by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1988 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.10...v9.5.11 - -## 9.5.10 - -* chore: remove dependency html converter by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1987 -* Fix: LineHeight button to use MenuAnchor by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/1986 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.9...v9.5.10 - -## 9.5.9 - -* Update pubspec.yaml to remove html2md by @singerdmx in https://github.com/singerdmx/flutter-quill/pull/1985 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.8...v9.5.9 - -## 9.5.8 - -* fix(typo): fix typo ClipboardServiceProvider.instacne by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1983 -* Feat: New way to get Delta from HTML inputs by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1984 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.7...v9.5.8 - -## 9.5.7 - -* refactor: context menu function, add test code by @n7484443 in https://github.com/singerdmx/flutter-quill/pull/1979 -* Fix: PreserveInlineStylesRule by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/1980 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.6...v9.5.7 - -## 9.5.6 - -* fix: common link is detected as a video link by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1978 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.5...v9.5.6 - -## 9.5.5 - -* fix: context menu behavior in mouse, desktop env by @n7484443 in https://github.com/singerdmx/flutter-quill/pull/1976 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.4...v9.5.5 - -## 9.5.4 - -* Feat: Line height support by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1972 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.3...v9.5.4 - -## 9.5.3 - -* Perf: Performance optimization by @Alspb in https://github.com/singerdmx/flutter-quill/pull/1964 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.2...v9.5.3 - -## 9.5.2 - -* Fix style settings by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/1962 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.1...v9.5.2 - -## 9.5.1 - -* feat(extensions): Youtube Video Player Support Mode by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1916 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.5.0...v9.5.1 - -## 9.5.0 - -* Partial support for table embed by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1960 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.9...v9.5.0 - -## 9.4.9 - -* Upgrade photo_view to 0.15.0 for flutter_quill_extensions by @singerdmx in https://github.com/singerdmx/flutter-quill/pull/1958 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.8...v9.4.9 - -## 9.4.8 - -* Add support for html underline and videos by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1955 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.7...v9.4.8 - -## 9.4.7 - -* fixed #1953 italic detection error by @CatHood0 in https://github.com/singerdmx/flutter-quill/pull/1954 - -## New Contributors -* @CatHood0 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1954 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.6...v9.4.7 - -## 9.4.6 - -* fix: search dialog throw an exception due to missing FlutterQuillLocalizations.delegate in the editor by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1938 -* fix(editor): implement editor shortcut action for home and end keys to fix exception about unimplemented ScrollToDocumentBoundaryIntent by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1937 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.5...v9.4.6 - -## 9.4.5 - -* fix: color picker hex unfocus on web by @geronimol in https://github.com/singerdmx/flutter-quill/pull/1934 - -## New Contributors -* @geronimol made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1934 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.4...v9.4.5 - -## 9.4.4 - -* fix: Enabled link regex to be overridden by @JoepHeijnen in https://github.com/singerdmx/flutter-quill/pull/1931 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.3...v9.4.4 - -## 9.4.3 - -* Fix: setState() called after dispose(): QuillToolbarClipboardButtonState #1895 by @windows7lake in https://github.com/singerdmx/flutter-quill/pull/1926 - -## New Contributors -* @windows7lake made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1926 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.2...v9.4.3 - -## 9.4.2 - -* Respect autofocus, closes #1923 by @Guillergood in https://github.com/singerdmx/flutter-quill/pull/1924 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.1...v9.4.2 - -## 9.4.1 - -* replace base64 regex string by @salba360496 in https://github.com/singerdmx/flutter-quill/pull/1919 - -## New Contributors -* @salba360496 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1919 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.4.0...v9.4.1 - -## 9.4.0 - -This release can be used without changing anything, although it can break the behavior a little, we provided a way to use the old behavior in `9.3.x` - -- Thanks to @Alspb, the search bar/dialog has been reworked for improved UI that fits **Material 3** look and feel, the search happens on the fly, and other minor changes, if you want the old search bar, you can restore it with one line if you're using `QuillSimpleToolbar`: - ```dart - QuillToolbar.simple( - configurations: QuillSimpleToolbarConfigurations( - searchButtonType: SearchButtonType.legacy, - ), - ) - ``` - While the changes are mostly to the `QuillToolbarSearchDialog` and it seems this should be `searchDialogType`, we provided the old button with the old dialog in case we update the button in the future. - - If you're using `QuillToolbarSearchButton` in a custom Toolbar, you don't need anything to get the new button. if you want the old button, use the `QuillToolbarLegacySearchButton` widget - - Consider using the improved button with the improved dialog as the legacy button might removed in future releases (for now, it's not deprecated) - -
- Before - - ![image](https://github.com/singerdmx/flutter-quill/assets/73608287/9b40ad03-717f-4518-95f1-8d9cad773b2b) - - -
- -
- Improved - - ![image](https://github.com/singerdmx/flutter-quill/assets/73608287/e581733d-63fa-4984-9c41-4a325a0a0c04) - -
- - For the detailed changes, see #1904 - -- Korean translations by @leegh519 in https://github.com/singerdmx/flutter-quill/pull/1911 - -- The usage of `super_clipboard` plugin in `flutter_quill` has been moved to the `flutter_quill_extensions` package, this will restore the old behavior in `8.x.x` though it will break the `onImagePaste`, `onGifPaste` and rich text pasting from HTML or Markdown, most of those features are available in `super_clipboard` plugin except `onImagePaste` which was available as we were using [pasteboard](https://pub.dev/packages/pasteboard), Unfortunately, it's no longer supported on recent versions of Flutter, and some functionalities such as an image from Clipboard and Html paste are not supported on some platforms such as Android, your project will continue to work, calls of `onImagePaste` and `onGifPaste` will be ignored unless you include [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) package in your project and call: - - ```dart - FlutterQuillExtensions.useSuperClipboardPlugin(); - ``` - Before using any `flutter_quill` widgets, this will restore the old behavior in `9.x.x` - - We initially wanted to publish `flutter_quill_super_clipboard` to allow: - - Using `super_clipboard` without `flutter_quill_extensions` packages and plugins - - Using `flutter_quill_extensions` with optional `super_clipboard` - - To simplify the usage, we moved it to `flutter_quill_extensions`, let us know if you want any of the use cases above. - - Overall `super_clipboard` is a Comprehensive clipboard plugin with a lot of features, the only thing that developers didn't want is Rust installation even though it's automated. - - The main goal of `ClipboardService` is to make `super_clipboard` optional, you can use your own implementation, and create a class that implements `ClipboardService`, which you can get by: - ```dart - // ignore: implementation_imports - import 'package:flutter_quill/src/services/clipboard/clipboard_service.dart'; - ``` - - Then you can call: - ```dart - // ignore: implementation_imports -import 'package:flutter_quill/src/services/clipboard/clipboard_service_provider.dart'; - ClipboardServiceProvider.setInstance(YourClipboardService()); -``` - - The interface could change at any time and will be updated internally for `flutter_quill` and `flutter_quill_extensions`, we didn't export those two classes by default to avoid breaking changes in case you use them as we might change them in the future. - - If you use the above imports, you might get **breaking changes** in **non-breaking change releases**. - -- Subscript and Superscript should now work for all languages and characters - - The previous implementation required the Apple 'SF-Pro-Display-Regular.otf' font which is only licensed/permitted for use on Apple devices. -We have removed the Apple font from the example - -- Allow pasting Markdown and HTML file content from the system to the editor - - Before `9.4.x` if you try to copy an HTML or Markdown file, and paste it into the editor, you will get the file name in the editor - Copying an HTML file, or HTML content from apps and websites is different than copying plain text. - - This is why this change requires `super_clipboard` implementation as this is platform-dependent: - ```dart - FlutterQuillExtensions.useSuperClipboardPlugin(); - ``` - as mentioned above. - - The following example for copying a Markdown file: - -
- Markdown File Content - - ```md - - **Note**: This package supports converting from HTML back to Quill delta but it's experimental and used internally when pasting HTML content from the clipboard to the Quill Editor - - You have two options: - - 1. Using [quill_html_converter](./quill_html_converter/) to convert to HTML, the package can convert the Quill delta to HTML well - (it uses [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html)), it is just a handy extension to do it more quickly - 1. Another option is to use - [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html) to convert your document - to HTML. - This package has full support for all Quill operations—including images, videos, formulas, - tables, and mentions. - Conversion can be performed in vanilla Dart (i.e., server-side or CLI) or in Flutter. - It is a complete Dart part of the popular and mature [quill-delta-to-html](https://www.npmjs.com/package/quill-delta-to-html) - Typescript/Javascript package. - this package doesn't convert the HTML back to Quill Delta as far as we know - - ``` - -
- -
- Before - - ![image](https://github.com/singerdmx/flutter-quill/assets/73608287/03f5ae20-796c-4e8b-8668-09a994211c1e) - -
- -
- After - - ![image](https://github.com/singerdmx/flutter-quill/assets/73608287/7e3a1987-36e7-4665-944a-add87d24e788) - -
- - Markdown, and HTML converting from and to Delta are **currently far from perfect**, the current implementation could improved a lot - however **it will likely not work like expected**, due to differences between HTML and Delta, see this [comment](https://github.com/slab/quill/issues/1551#issuecomment-311458570) for more info. - - ![Copying Markdown file into Flutter Quill Editor](https://github.com/singerdmx/flutter-quill/assets/73608287/63bd6ba6-cc49-4335-84dc-91a0fa5c95a9) - - For more details see #1915 - - Using or converting to HTML or Markdown is highly experimental and shouldn't be used for production applications. - - We use it internally as it is more suitable for our specific use case., copying content from external websites and pasting it into the editor - previously breaks the styles, while the current implementation is not ready, it provides a better user experience and doesn't have many downsides. - - Feel free to report any bugs or feature requests at [Issues](https://github.com/singerdmx/flutter-quill/issues) or drop any suggestions and questions at [Discussions](https://github.com/singerdmx/flutter-quill/discussions) - -## New Contributors -* @leegh519 made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1911 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.21...v9.4.0 - -## 9.3.21 - -* fix: assertion failure for swipe typing and undo on Android by @crasowas in https://github.com/singerdmx/flutter-quill/pull/1898 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.20...v9.3.21 - -## 9.3.20 - -* Fix: Issue 1887 by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/1892 -* fix: toolbar style change will be invalid when inputting more than 2 characters at a time by @crasowas in https://github.com/singerdmx/flutter-quill/pull/1890 - -## New Contributors -* @crasowas made their first contribution in https://github.com/singerdmx/flutter-quill/pull/1890 - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.19...v9.3.20 - -## 9.3.19 - -* Fix reported issues by @AtlasAutocode in https://github.com/singerdmx/flutter-quill/pull/1886 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.18...v9.3.19 - -## 9.3.18 - -* Fix: Undo/redo cursor position fixed by @Alspb in https://github.com/singerdmx/flutter-quill/pull/1885 - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.17...v9.3.18 - -## 9.3.17 - -* Update super_clipboard plugin to 0.8.15 to address [#1882](https://github.com/singerdmx/flutter-quill/issues/1882) - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.16...v9.3.17 - -## 9.3.16 - -* Update `lint` dev package to 4.0.0 -* Require at least version 0.8.13 of the plugin - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.15...v9.3.16 - -## 9.3.15 - - -* Ci/automate updating the files by @ellet0 in https://github.com/singerdmx/flutter-quill/pull/1879 -* Updating outdated README.md and adding a few guidelines for CONTRIBUTING.md - - -**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v9.3.14...v9.3.15 - -## 9.3.14 - -* Chore/use original color picker package in [#1877](https://github.com/singerdmx/flutter-quill/pull/1877) - -## 9.3.13 - -* fix: `readOnlyMouseCursor` losing in construction function -* Fix block multi-line selection style - -## 9.3.12 - -* Add `readOnlyMouseCursor` to config mouse cursor type - -## 9.3.11 - -* Fix typo in QuillHtmlConverter -* Fix re-create checkbox - -## 9.3.10 - -* Support clipboard actions from the toolbar - -## 9.3.9 - -* fix: MD Parsing for multi space -* fix: FontFamily and FontSize toolbars track the text selected in the editor -* feat: Add checkBoxReadOnly property which can override readOnly for checkbox - -## 9.3.8 - -* fix: removed misleading parameters -* fix: added missed translations for ru, es, de -* added translations for Nepali Locale('ne', 'NP') - -## 9.3.7 - -* Fix for keyboard jumping when switching focus from a TextField -* Toolbar button styling to reflect cursor position when running on desktops with keyboard to move care - -## 9.3.6 - -* Add SK and update CS locales [#1796](https://github.com/singerdmx/flutter-quill/pull/1796) -* Fixes: - * QuillIconTheme changes for FontFamily and FontSize buttons are not applied [#1797](https://github.com/singerdmx/flutter-quill/pull/1796) - * Make the arrow_drop_down icons in the QuillToolbar the same size for all MenuAnchor buttons [#1799](https://github.com/singerdmx/flutter-quill/pull/1796) - -## 9.3.5 - -* Update the minimum version for the packages to support `device_info_plus` version 10.0.0 [#1783](https://github.com/singerdmx/flutter-quill/issues/1783) -* Update the minimum version for `youtube_player_flutter` to new major version 9.0.0 in the `flutter_quill_extensions` - -## 9.3.4 - -* fix: multiline styling stuck/not working properly [#1782](https://github.com/singerdmx/flutter-quill/pull/1782) - -## 9.3.3 - -* Update `quill_html_converter` versions - -## 9.3.2 - -* Fix dispose of text painter [#1774](https://github.com/singerdmx/flutter-quill/pull/1774) - -## 9.3.1 - -* Require Flutter 3.19.0 as minimum version - -## 9.3.0 - -* **Breaking change**: `Document.fromHtml(html)` is now returns `Document` instead of `Delta`, use `DeltaX.fromHtml` to return `Delta` -* Update old deprecated api from Flutter 3.19 -* Scribble scroll fix by @mtallenca in https://github.com/singerdmx/flutter-quill/pull/1745 - -## 9.2.14 - -* feat: move cursor after inserting video/image -* Apple pencil - -## 9.2.13 - -* Fix crash with inserting text from contextMenuButtonItems -* Fix incorrect behaviour of context menu -* fix: selection handles behaviour and unnessesary style assert -* Update quill_fr.arb - -## 9.2.12 - -* Fix safari clipboard bug -* Add the option to disable clipboard functionality - -## 9.2.11 - -* Fix a bug where it has problems with pasting text into the editor when the clipboard has styled text - -## 9.2.10 - -* Update example screenshots -* Refactor `Container` to `QuillContainer` with backward compatibility -* A workaround fix in history feature - -## 9.2.9 - -* Refactor the type of `Delta().toJson()` to be more clear type - -## 9.2.8 - -* feat: Export Container node as QuillContainer -* fix web cursor position / height (don't use iOS logic) -* Added Swedish translation - -## 9.2.6 - -* [fix selection.affinity always downstream after updateEditingValue](https://github.com/singerdmx/flutter-quill/pull/1682) -* Bumb version of `super_clipboard` - -## 9.2.5 - -* Bumb version of `super_clipboard` - -## 9.2.4 - -* Use fixed version of intl - -## 9.2.3 - -* remove unncessary column in Flutter quill video embed block - -## 9.2.2 - -* Fix bug [#1627](https://github.com/singerdmx/flutter-quill/issues/1627) - -## 9.2.1 - -* Fix [bug](https://github.com/singerdmx/flutter-quill/issues/1119#issuecomment-1872605246) with font size button -* Added ro RO translations -* 📖 Update zh, zh_CN translations - -## 9.2.0 - -* Require minimum version `6.0.0` of `flutter_keyboard_visibility` to fix some build issues with Android Gradle Plugin 8.2.0 -* Add on image clicked in `flutter_quill_extensions` callback -* Deprecate `globalIconSize` and `globalIconButtonFactor`, use `iconSize` and `iconButtonFactor` instead -* Fix the `QuillToolbarSelectAlignmentButtons` - -## 9.1.1 - -* Require `super_clipboard` minimum version `0.8.1` to fix some bug with Linux build failure - -## 9.1.1-dev - -* Fix bug [#1636](https://github.com/singerdmx/flutter-quill/issues/1636) -* Fix a where you paste styled content (HTML) it always insert a new line at first even if the document is empty -* Fix the font size button and migrate to `MenuAnchor` -* The `defaultDisplayText` is no longer required in the font size and header dropdown buttons -* Add pdf converter in a new package (`quill_pdf_converter`) - -## 9.1.0 - -* Fix the simple toolbar by add properties of `IconButton` and fix some buttons - -## 9.1.0-dev.2 - -* Fix the history buttons - -## 9.1.0-dev.1 - -* Bug fixes in the simple toolbar buttons - -## 9.1.0-dev - -* **Breaking Change**: in the `QuillSimpleToolbar` Fix the `QuillIconTheme` by replacing all the properties with two properties of type `ButtonStyle`, use `IconButton.styleFrom()` - -## 9.0.6 - -* Fix bug in QuillToolbarSelectAlignmentButtons - -## 9.0.5 - -* You can now use most of the buttons without internal provider - -## 9.0.4 - -* Feature: [#1611](https://github.com/singerdmx/flutter-quill/issues/1611) -* Export missing widgets - -## 9.0.3 - -* Flutter Quill Extensions: - * Fix file image support for web image emebed builder - -## 9.0.2 - -* Remove unused properties in the `QuillToolbarSelectHeaderStyleDropdownButton` -* Fix the `QuillSimpleToolbar` when `useMaterial3` is false, please upgrade to the latest version of flutter for better support - -## 9.0.2-dev.3 - -* Export `QuillSingleChildScrollView` - -## 9.0.2-dev.2 - -* Add the new translations for ru, uk arb files by [#1575](https://github.com/singerdmx/flutter-quill/pull/1575) -* Add a new dropdown button by [#1575](https://github.com/singerdmx/flutter-quill/pull/1575) -* Update the default style values by [#1575](https://github.com/singerdmx/flutter-quill/pull/1575) -* Fix bug [#1562](https://github.com/singerdmx/flutter-quill/issues/1562) -* Fix the second bug of [#1480](https://github.com/singerdmx/flutter-quill/issues/1480) - -## 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 -* Add `toolbarRunSpacing` property to the simple toolbar - -## 9.0.1 - -* Fix default icon size - -## 9.0.0 - -* This version is quite stable but it's not how we wanted to be, because the lack of time and there are not too many maintainers active, we decided to publish it, we might make a new breaking changes verion - -## 9.0.1-dev.1 - -* Flutter Quill Extensions: - * Update `QuillImageUtilities` and fixining some bugs - -## 9.0.1-dev - -* Test new GitHub workflows - -## 9.0.0-dev-10 - -* Fix a bug of the improved pasting HTML contents contents into the editor - -## 9.0.0-dev-9 - -* Improves the new logic of pasting HTML contents into the Editor -* Update `README.md` and the doc -* Dispose the `QuillToolbarSelectHeaderStyleButton` state listener in `dispose` -* Upgrade the font family button to material 3 -* Rework the font family and font size functionalities to change the font once and type all over the editor - -## 9.0.0-dev-8 - -* Better support for pasting HTML contents from external websites to the editor -* The experimental support of converting the HTML from `quill_html_converter` is now built-in in the `flutter_quill` and removed from there (Breaking change for `quill_html_converter`) - -## 9.0.0-dev-7 - -* Fix a bug in chaning the background/font color of ol/ul list -* Flutter Quill Extensions: - * Fix link bug in the video url - * Fix patterns - -## 9.0.0-dev-6 - -* Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly -* Bug fixes -* Add the ability to change the background and font color of the ol/ul elements dots and numbers -* Flutter Quill Extensions: - * **Breaking Change**: The `imageProviderBuilder`is now providing the context and image url - -## 9.0.0-dev-5 - -* The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard -* Flutter Quill Extensions: - * Improve the camera button - -## 9.0.0-dev-4 - -* The options parameter in all of the buttons is no longer required which can be useful to create custom toolbar with minimal efforts -* Toolbar buttons fixes in both `flutter_quill` and `flutter_quill_extensions` -* The `QuillProvider` has been dropped and no longer used, the providers will be used only internally from now on and we will not using them as much as possible - -## 9.0.0-dev-3 - -* Breaking Changes: - * Rename `QuillToolbar` to `QuillSimpleToolbar` - * Rename `QuillBaseToolbar` to `QuillToolbar` - * Replace `pasteboard` with `rich_cliboard` -* Fix a bug in the example when inserting an image from url -* Flutter Quill Extensions: - * Add support for copying the image to the system cliboard - -## 9.0.0-dev-2 - -* An attemp to fix CI automated publishing - -## 9.0.0-dev-1 - -* An attemp to fix CI automated publishing - -## 9.0.0-dev - -* **Major Breaking change**: The `QuillProvider` is now optional, the `controller` parameter has been moved to the `QuillEditor` and `QuillToolbar` once again. -* Flutter Quill Extensions; - * **Breaking Change**: Completly change the way how the source code structured to more basic and simple way, organize folders and file names, if you use the library -from `flutter_quill_extensions.dart` then there is nothing you need to do, but if you are using any other import then you need to re-imports -embed, this won't affect how quill js work - * Improvemenets to the image embed - * Add support for `margin` for web - * Add untranslated strings to the `quill_en.arb` - -## 8.6.4 - -* The default value of `keyboardAppearance` for the iOS will be the one from the App/System theme mode instead of always using the `Brightness.light` -* Fix typos in `README.md` - -## 8.6.3 - -* Update the minimum flutter version to `3.16.0` - -## 8.6.2 - -* Restore use of alternative QuillToolbarLinkStyleButton2 widget - -## 8.6.1 - -* Temporary revert style bug fix - -## 8.6.0 - -* **Breaking Change** Support [Flutter 3.16](https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1), please upgrade to the latest stable version of flutter to use this update -* **Breaking Change**: Remove Deprecated Fields -* **Breaking Change**: Extract the shared things between `QuillToolbarConfigurations` and `QuillBaseToolbarConfigurations` -* **Breaking Change**: You no longer need to use `QuillToolbarProvider` when using custom toolbar buttons, the example has been updated -* Bug fixes - -## 8.5.5 - -* Now when opening dialogs by `QuillToolbar` you will not get an exception when you don't use `FlutterQuillLocalizations.delegate` in your `WidgetsApp`, `MaterialApp`, or `CupertinoApp`. The fix is for the `QuillToolbarSearchButton`, `QuillToolbarLinkStyleButton`, and `QuillToolbarColorButton` buttons - -## 8.5.4 - -* The `mobileWidth`, `mobileHeight`, `mobileMargin`, and `mobileAlignment` is now deprecated in `flutter_quill`, they are now defined in `flutter_quill_extensions` -* Deprecate `replaceStyleStringWithSize` function which is in `string.dart` -* Deprecate `alignment`, and `margin` as they don't conform to official Quill JS - -## 8.5.3 - -* Update doc -* Update `README.md` and `CHANGELOG.md` -* Fix typos -* Use `immutable` when possible -* Update `.pubignore` - -## 8.5.2 - -* Updated `README.md`. -* Feature: Added the ability to include a custom callback when the `QuillToolbarColorButton` is pressed. -* The `QuillToolbar` now implements `PreferredSizeWidget`, enabling usage in the AppBar, similar to `QuillBaseToolbar`. - -## 8.5.1 - -* Updated `README.md`. - -## 8.5.0 - -* Migrated to `flutter_localizations` for translations. -* Fixed: Translated all previously untranslated localizations. -* Fixed: Added translations for missing items. -* Fixed: Introduced default Chinese fallback translation. -* Removed: Unused parameters `items` in `QuillToolbarFontFamilyButtonOptions` and `QuillToolbarFontSizeButtonOptions`. -* Updated: Documentation. - -## 8.4.4 - -* Updated `.pubignore` to ignore unnecessary files and folders. - -## 8.4.3 - -* Updated `CHANGELOG.md`. - -## 8.4.2 - -* **Breaking change**: Configuration for `QuillRawEditor` has been moved to a separate class. Additionally, `readOnly` has been renamed to `isReadOnly`. If using `QuillEditor`, no action is required. -* Introduced the ability for developers to override `TextInputAction` in both `QuillRawEditor` and `QuillEditor`. -* Enabled using `QuillRawEditor` without `QuillEditorProvider`. -* Bug fixes. -* Added image cropping implementation in the example. - -## 8.4.1 - -* Added `copyWith` in `OptionalSize` class. - -## 8.4.0 - -* **Breaking change**: Updated `QuillCustomButton` to use `QuillCustomButtonOptions`. Moved all properties from `QuillCustomButton` to `QuillCustomButtonOptions`, replacing `iconData` with `icon` widget for increased customization. -* **Breaking change**: `customButtons` in `QuillToolbarConfigurations` is now of type `List`. -* Bug fixes following the `8.0.0` update. -* Updated `README.md`. -* Improved platform checking. - -## 8.3.0 - -* Added `iconButtonFactor` property to `QuillToolbarBaseButtonOptions` for customizing button size relative to its icon size (defaults to `kIconButtonFactor`, consistent with previous releases). - -## 8.2.6 - -* Organized `QuillRawEditor` code. - -## 8.2.5 - -* Added `builder` property in `QuillEditorConfigurations`. - -## 8.2.4 - -* Adhered to Flutter best practices. -* Fixed auto-focus bug. - -## 8.2.3 - -* Updated `README.md`. - -## 8.2.2 - -* Moved `flutter_quill_test` to a separate package: [flutter_quill_test](https://pub.dev/packages/flutter_quill_test). - -## 8.2.1 - -* Updated `README.md`. - -## 8.2.0 - -* Added the option to add configurations for `flutter_quill_extensions` using `extraConfigurations`. - -## 8.1.11 - -* Followed Dart best practices by using `lints` and removed `pedantic` and `platform` since they are not used. -* Fixed text direction bug. -* Updated `README.md`. - -## 8.1.10 - -* Secret for automated publishing to pub.dev. - -## 8.1.9 - -* Fixed automated publishing to pub.dev. - -## 8.1.8 - -* Fixed automated publishing to pub.dev. - -## 8.1.7 - -* Automated publishing to pub.dev. - -## 8.1.6 - -* Fixed compatibility with `integration_test` by downgrading the minimum version of the platform package to 3.1.0. - -## 8.1.5 - -* Reversed background/font color toolbar button icons. - -## 8.1.4 - -* Reversed background/font color toolbar button tooltips. - -## 8.1.3 - -* Moved images to screenshots instead of `README.md`. - -## 8.1.2 - -* Fixed a bug related to the regexp of the insert link dialog. -* Required Dart 3 as the minimum version. -* Code cleanup. -* Added a spacer widget between each button in the `QuillToolbar`. - -## 8.1.1 - -* Fixed null error in line.dart #1487(https://github.com/singerdmx/flutter*quill/issues/1487). - -## 8.1.0 - -* Fixed a word typo of `mirgration` to `migration` in the readme & migration document. -* Updated migration guide. -* Removed property `enableUnfocusOnTapOutside` in `QuillEditor` configurations and added `isOnTapOutsideEnabled` instead. -* Added a new callback called `onTapOutside` in the `QuillEditorConfigurations` to perform actions when tapping outside the editor. -* Fixed a bug that caused the web platform to not unfocus the editor when tapping outside of it. To override this, please pass a value to the `onTapOutside` callback. -* Removed the old property of `iconTheme`. Instead, pass `iconTheme` in the button options; you will find the `base` property inside it with `iconTheme`. - -## 8.0.0 - -* If you have migrated recently, don't be alarmed by this update; it adds documentation, a migration guide, and marks the version as a more stable release. Although there are breaking changes (as reported by some developers), the major version was not changed due to time constraints during development. A single property was also renamed from `code` to `codeBlock` in the `elements` of the new `QuillEditorConfigurations` class. -* Updated the README for better readability. - -## 7.10.2 - -* Removed line numbers from code blocks by default. You can still enable this feature thanks to the new configurations in the `QuillEditor`. Find the `elementOptions` property and enable `enableLineNumbers`. - -## 7.10.1 - -* Fixed issues and utilized the new parameters. -* No longer need to use `MaterialApp` for most toolbar button child builders. -* Compatibility with [fresh_quill_extensions](https://pub.dev/packages/fresh_quill_extensions), a temporary alternative to [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions). -* Updated most of the documentation in `README.md`. - -## 7.10.0 - -* **Breaking change**: `QuillToolbar.basic()` can be accessed directly from `QuillToolbar()`, and the old `QuillToolbar` can be accessed from `QuillBaseToolbar`. -* Refactored Quill editor and toolbar configurations into a single class each. -* After changing checkbox list values, the controller will not request keyboard focus by default. -* Moved toolbar and editor configurations directly into the widget but still use inherited widgets internally. -* Fixes to some code after the refactoring. - -## 7.9.0 - -* Buttons Improvemenets -* Refactor all the button configurations that used in `QuillToolbar.basic()` but there are still few lefts -* **Breaking change**: Remove some configurations from the QuillToolbar and move them to the new `QuillProvider`, please notice this is a development version and this might be changed in the next few days, the stable release will be ready in less than 3 weeks -* Update `flutter_quill_extensions` and it will be published into pub.dev soon. -* Allow you to customize the search dialog by custom callback with child builder - -## 7.8.0 - -* **Important note**: this is not test release yet, it works but need more test and changes and breaking changes, we don't have development version and it will help us if you try the latest version and report the issues in Github but if you want a stable version please use `7.4.16`. this refactoring process will not take long and should be done less than three weeks with the testing. -* We managed to refactor most of the buttons configurations and customizations in the `QuillProvider`, only three lefts then will start on refactoring the toolbar configurations -* Code improvemenets - -## 7.7.0 - -* **Breaking change**: We have mirgrated more buttons in the toolbar configurations, you can do change them in the `QuillProvider` -* Important bug fixes - -## 7.6.1 - -* Bug fixes - -## 7.6.0 - -* **Breaking change**: To customize the buttons in the toolbar, you can do that in the `QuillProvider` - -## 7.5.0 - -* **Breaking change**: The widgets `QuillEditor` and `QuillToolbar` are no longer have controller parameter, instead you need to make sure in the widget tree you have wrapped them with `QuillProvider` widget and provide the controller and the require configurations - -## 7.4.16 - -* Update documentation and README.md - -## 7.4.15 - -* Custom style attrbuites for platforms other than mobile (alignment, margin, width, height) -* Bug fixes and other improvemenets - -## 7.4.14 - -* Improve performance by reducing the number of widgets rebuilt by listening to media query for only the needed things, for example instead of using `MediaQuery.of(context).size`, now we are using `MediaQuery.sizeOf(context)` -* Add MediaButton for picking the images only since the video one is not ready -* A new feature which allows customizing the text selection in quill editor which is useful for custom theme design system for custom app widget - -## 7.4.13 - -* Fixed tab editing when in readOnly mode. - -## 7.4.12 - -* Update the minimum version of device_info_plus to 9.1.0. - -## 7.4.11 - -* Add sw locale. - -## 7.4.10 - -* Update translations. - -## 7.4.9 - -* Style recognition fixes. - -## 7.4.8 - -* Upgrade dependencies. - -## 7.4.7 - -* Add Vietnamese and German translations. - -## 7.4.6 - -* Fix more null errors in Leaf.retain [##1394](https://github.com/singerdmx/flutter-quill/issues/1394) and Line.delete [##1395](https://github.com/singerdmx/flutter-quill/issues/1395). - -## 7.4.5 - -* Fix null error in Container.insert [##1392](https://github.com/singerdmx/flutter-quill/issues/1392). - -## 7.4.4 - -* Fix extra padding on checklists [##1131](https://github.com/singerdmx/flutter-quill/issues/1131). - -## 7.4.3 - -* Fixed a space input error on iPad. - -## 7.4.2 - -* Fix bug with keepStyleOnNewLine for link. - -## 7.4.1 - -* Fix toolbar dividers condition. - -## 7.4.0 - -* Support Flutter version 3.13.0. - -## 7.3.3 - -* Updated Dependencies conflicting. - -## 7.3.2 - -* Added builder for custom button in _LinkDialog. - -## 7.3.1 - -* Added case sensitive and whole word search parameters. -* Added wrap around. -* Moved search dialog to the bottom in order not to override the editor and the text found. -* Other minor search dialog enhancements. - -## 7.3.0 - -* Add default attributes to basic factory. - -## 7.2.19 - -* Feat/link regexp. - -## 7.2.18 - -* Fix paste block text in words apply same style. - -## 7.2.17 - -* Fix paste text mess up style. -* Add support copy/cut block text. - -## 7.2.16 - -* Allow for custom context menu. - -## 7.2.15 - -* Add flutter_quill.delta library which only exposes Delta datatype. - -## 7.2.14 - -* Fix errors when the editor is used in the `screenshot` package. - -## 7.2.13 - -* Fix around image can't delete line break. - -## 7.2.12 - -* Add support for copy/cut select image and text together. - -## 7.2.11 - -* Add affinity for localPosition. - -## 7.2.10 - -* LINE._getPlainText queryChild inclusive=false. - -## 7.2.9 - -* Add toPlainText method to `EmbedBuilder`. - -## 7.2.8 - -* Add custom button widget in toolbar. - -## 7.2.7 - -* Fix language code of Japan. - -## 7.2.6 - -* Style custom toolbar buttons like builtins. - -## 7.2.5 - -* Always use text cursor for editor on desktop. - -## 7.2.4 - -* Fixed keepStyleOnNewLine. - -## 7.2.3 - -* Get pixel ratio from view. - -## 7.2.2 - -* Prevent operations on stale editor state. - -## 7.2.1 - -* Add support for android keyboard content insertion. -* Enhance color picker, enter hex color and color palette option. - -## 7.2.0 - -* Checkboxes, bullet points, and number points are now scaled based on the default paragraph font size. - -## 7.1.20 - -* Pass linestyle to embedded block. - -## 7.1.19 - -* Fix Rtl leading alignment problem. - -## 7.1.18 - -* Support flutter latest version. - -## 7.1.17+1 - -* Updates `device_info_plus` to version 9.0.0 to benefit from AGP 8 (see [changelog##900](https://pub.dev/packages/device_info_plus/changelog##900)). - -## 7.1.16 - -* Fixed subscript key from 'sup' to 'sub'. - -## 7.1.15 - -* Fixed a bug introduced in 7.1.7 where each section in `QuillToolbar` was displayed on its own line. - -## 7.1.14 - -* Add indents change for multiline selection. - -## 7.1.13 - -* Add custom recognizer. - -## 7.1.12 - -* Add superscript and subscript styles. - -## 7.1.11 - -* Add inserting indents for lines of list if text is selected. - -## 7.1.10 - -* Image embedding tweaks - * Add MediaButton which is intened to superseed the ImageButton and VideoButton. Only image selection is working. - * Implement image insert for web (image as base64) - -## 7.1.9 - -* Editor tweaks PR from bambinoua(https://github.com/bambinoua). - * Shortcuts now working in Mac OS - * QuillDialogTheme is extended with new properties buttonStyle, linkDialogConstraints, imageDialogConstraints, isWrappable, runSpacing, - * Added LinkStyleButton2 with new LinkStyleDialog (similar to Quill implementation - * Conditinally use Row or Wrap for dialog's children. - * Update minimum Dart SDK version to 2.17.0 to use enum extensions. - * Use merging shortcuts and actions correclty (if the key combination is the same) - -## 7.1.8 - -* Dropdown tweaks - * Add itemHeight, itemPadding, defaultItemColor for customization of dropdown items. - * Remove alignment property as useless. - * Fix bugs with max width when width property is null. - -## 7.1.7 - -* Toolbar tweaks. - * Implement tooltips for embed CameraButton, VideoButton, FormulaButton, ImageButton. - * Extends customization for SelectAlignmentButton, QuillFontFamilyButton, QuillFontSizeButton adding padding, text style, alignment, width. - * Add renderFontFamilies to QuillFontFamilyButton to show font faces in dropdown. - * Add AxisDivider and its named constructors for for use in parent project. - * Export ToolbarButtons enum to allow specify tooltips for SelectAlignmentButton. - * Export QuillFontFamilyButton, SearchButton as they were not exported before. - * Deprecate items property in QuillFontFamilyButton, QuillFontSizeButton as the it can be built usinr rawItemsMap. - * Make onSelection QuillFontFamilyButton, QuillFontSizeButton omittable as no need to execute callback outside if controller is passed to widget. - -Now the package is more friendly for web projects. - -## 7.1.6 - -* Add enableUnfocusOnTapOutside field to RawEditor and Editor widgets. - -## 7.1.5 - -* Add tooltips for toolbar buttons. - -## 7.1.4 - -* Fix inserting tab character in lists. - -## 7.1.3 - -* Fix ios cursor bug when word.length==1. - -## 7.1.2 - -* Fix non scrollable editor exception, when tapped under content. - -## 7.1.1 - -* customLinkPrefixes parameter * makes possible to open links with custom protoco. - -## 7.1.0 - -* Fix ordered list numeration with several lists in document. - -## 7.0.9 - -* Use const constructor for EmbedBuilder. - -## 7.0.8 - -* Fix IME position bug with scroller. - -## 7.0.7 - -* Add TextFieldTapRegion for contextMenu. - -## 7.0.6 - -* Fix line style loss on new line from non string. - -## 7.0.5 - -* Fix IME position bug for Mac and Windows. -* Unfocus when tap outside editor. fix the bug that cant refocus in afterButtonPressed after click ToggleStyleButton on Mac. - -## 7.0.4 - -* Have text selection span full line height for uneven sized text. - -## 7.0.3 - -* Fix ordered list numeration for lists with more than one level of list. - -## 7.0.2 - -* Allow widgets to override widget span properties. - -## 7.0.1 - -* Update i18n_extension dependency to version 8.0.0. - -## 7.0.0 - -* Breaking change: Tuples are no longer used. They have been replaced with a number of data classes. - -## 6.4.4 - -* Increased compatibility with Flutter widget tests. - -## 6.4.3 - -* Update dependencies (collection: 1.17.0, flutter_keyboard_visibility: 5.4.0, quiver: 3.2.1, tuple: 2.0.1, url_launcher: 6.1.9, characters: 1.2.1, i18n_extension: 7.0.0, device_info_plus: 8.1.0) - -## 6.4.2 - -* Replace `buildToolbar` with `contextMenuBuilder`. - -## 6.4.1 - -* Control the detect word boundary behaviour. - -## 6.4.0 - -* Use `axis` to make the toolbar vertical. -* Use `toolbarIconCrossAlignment` to align the toolbar icons on the cross axis. -* Breaking change: `QuillToolbar`'s parameter `toolbarHeight` was renamed to `toolbarSize`. - -## 6.3.5 - -* Ability to add custom shortcuts. - -## 6.3.4 - -* Update clipboard status prior to showing selected text overlay. - -## 6.3.3 - -* Fixed handling of mac intents. - -## 6.3.2 - -* Added `unknownEmbedBuilder` to QuillEditor. -* Fix error style when input chinese japanese or korean. - -## 6.3.1 - -* Add color property to the basic factory function. - -## 6.3.0 - -* Support Flutter 3.7. - -## 6.2.2 - -* Fix: nextLine getter null where no assertion. - -## 6.2.1 - -* Revert "Align numerical and bullet lists along with text content". - -## 6.2.0 - -* Align numerical and bullet lists along with text content. - -## 6.1.12 - -* Apply i18n for default font dropdown option labels corresponding to 'Clear'. - -## 6.1.11 - -* Remove iOS hack for delaying focus calculation. - -## 6.1.10 - -* Delay focus calculation for iOS. - -## 6.1.9 - -* Bump keyboard show up wait to 1 sec. - -## 6.1.8 - -* Recalculate focus when showing keyboard. - -## 6.1.7 - -* Add czech localizations. - -## 6.1.6 - -* Upgrade i18n_extension to 6.0.0. - -## 6.1.5 - -* Fix formatting exception. - -## 6.1.4 - -* Add double quotes validation. - -## 6.1.3 - -* Revert "fix order list numbering (##988)". - -## 6.1.2 - -* Add typing shortcuts. - -## 6.1.1 - -* Fix order list numbering. - -## 6.1.0 - -* Add keyboard shortcuts for editor actions. - -## 6.0.10 - -* Upgrade device info plus to ^7.0.0. - -## 6.0.9 - -* Don't throw showAutocorrectionPromptRect not implemented. The function is called with every keystroke as a user is typing. - -## 6.0.8+1 - -* Fixes null pointer when setting documents. - -## 6.0.8 - -* Make QuillController.document mutable. - -## 6.0.7 - -* Allow disabling of selection toolbar. - -## 6.0.6+1 - -* Revert 6.0.6. - -## 6.0.6 - -* Fix wrong custom embed key. - -## 6.0.5 - -* Fixes toolbar buttons stealing focus from editor. - -## 6.0.4 - -* Bug fix for Type 'Uint8List' not found. - -## 6.0.3 - -* Add ability to paste images. - -## 6.0.2 - -* Address Dart Analysis issues. - -## 6.0.1 - -* Changed translation country code (zh_HK -> zh_hk) to lower case, which is required for i18n_extension used in flutter_quill. -* Add localization in example's main to demonstrate translation. -* Issue Windows selection's copy / paste tool bar not shown ##861: add selection's copy / paste toolbar, escape to hide toolbar, mouse right click to show toolbar, ctrl-Y / ctrl-Z to undo / redo. -* Image and video displayed in Windows platform caused screen flickering while selecting text, a sample_data_nomedia.json asset is added for Desktop to demonstrate the added features. -* Known issue: keyboard action sometimes causes exception mentioned in Flutter's issue ##106475 (Windows Keyboard shortcuts stop working after modifier key repeat flutter/flutter##106475). -* Know issue: user needs to click the editor to get focus before toolbar is able to display. - -## 6.0.0 BREAKING CHANGE - -* Removed embed (image, video & formula) blocks from the package to reduce app size. - -These blocks have been moved to the package `flutter_quill_extensions`, migrate by filling the `embedBuilders` and `embedButtons` parameters as follows: - -``` -import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; - -QuillEditor.basic( - controller: controller, - embedBuilders: FlutterQuillEmbeds.builders(), -); - -QuillToolbar.basic( - controller: controller, - embedButtons: FlutterQuillEmbeds.buttons(), -); -``` - -## 5.4.2 - -* Upgrade i18n_extension. - -## 5.4.1 - -* Update German Translation. - -## 5.4.0 - -* Added Formula Button (for maths support). - -## 5.3.2 - -* Add more font family. - -## 5.3.1 - -* Enable search when text is not empty. - -## 5.3.0 - -* Added search function. - -## 5.2.11 - -* Remove default small color. - -## 5.2.10 - -* Don't wrap the QuillEditor's child in the EditorTextSelectionGestureDetector if selection is disabled. - -## 5.2.9 - -* Added option to modify SelectHeaderStyleButton options. -* Added option to click again on h1, h2, h3 button to go back to normal. - -## 5.2.8 - -* Remove tooltip for LinkStyleButton. -* Make link match regex case insensitive. - -## 5.2.7 - -* Add locale to QuillEditor.basic. - -## 5.2.6 - -* Fix keyboard pops up when resizing the image. - -## 5.2.5 - -* Upgrade youtube_player_flutter_quill to 8.2.2. - -## 5.2.4 - -* Upgrade youtube_player_flutter_quill to 8.2.1. - -## 5.2.3 - -* Flutter Quill Doesn't Work On iOS 16 or Xcode 14 Betas (Stored properties cannot be marked potentially unavailable with '@available'). - -## 5.2.2 - -* Fix Web Unsupported operation: Platform.\_operatingSystem error. - -## 5.2.1 - -* Rename QuillCustomIcon to QuillCustomButton. - -## 5.2.0 - -* Support font family selection. - -## 5.1.1 - -* Update README. - -## 5.1.0 - -* Added CustomBlockEmbed and customElementsEmbedBuilder. - -## 5.0.5 - -* Upgrade device_info_plus to 4.0.0. - -## 5.0.4 - -* Added onVideoInit callback for video documents. - -## 5.0.3 - -* Update dependencies. - -## 5.0.2 - -* Keep cursor position on checkbox tap. - -## 5.0.1 - -* Fix static analysis errors. - -## 5.0.0 - -* Flutter 3.0.0 support. - -## 4.2.3 - -* Ignore color:inherit and convert double to int for level. - -## 4.2.2 - -* Add clear option to font size dropdown. - -## 4.2.1 - -* Refactor font size dropdown. - -## 4.2.0 - -* Ensure selectionOverlay is available for showToolbar. - -## 4.1.9 - -* Using properly iconTheme colors. - -## 4.1.8 - -* Update font size dropdown. - -## 4.1.7 - -* Convert FontSize to a Map to allow for named Font Size. - -## 4.1.6 - -* Update quill_dropdown_button.dart. - -## 4.1.5 - -* Add Font Size dropdown to the toolbar. - -## 4.1.4 - -* New borderRadius for iconTheme. - -## 4.1.3 - -* Fix selection handles show/hide after paste, backspace, copy. - -## 4.1.2 - -* Add full support for hardware keyboards (Chromebook, Android tablets, etc) that don't alter screen UI. - -## 4.1.1 - -* Added textSelectionControls field in QuillEditor. - -## 4.1.0 - -* Added Node to linkActionPickerDelegate. - -## 4.0.12 - -* Add Persian(fa) language. - -## 4.0.11 - -* Fix cut selection error in multi-node line. - -## 4.0.10 - -* Fix vertical caret position bug. - -## 4.0.9 - -* Request keyboard focus when no child is found. - -## 4.0.8 - -* Fix blank lines do not display when **web*renderer=html. - -## 4.0.7 - -* Refactor getPlainText (better handling of blank lines and lines with multiple markups. - -## 4.0.6 - -* Bug fix for copying text with new lines. - -## 4.0.5 - -* Fixed casting null to Tuple2 when link dialog is dismissed without any input (e.g. barrier dismissed). - -## 4.0.4 - -* Bug fix for text direction rtl. - -## 4.0.3 - -* Support text direction rtl. - -## 4.0.2 - -* Clear toggled style on selection change. - -## 4.0.1 - -* Fix copy/cut/paste/selectAll not working. - -## 4.0.0 - -* Upgrade for Flutter 2.10. - -## 3.9.11 - -* Added Indonesian translation. - -## 3.9.10 - -* Fix for undoing a modification ending with an indented line. - -## 3.9.9 - -* iOS: Save image whose filename does not end with image file extension. - -## 3.9.8 - -* Added Urdu translation. - -## 3.9.7 - -* Fix for clicking on the Link button without any text on a new line crashes. - -## 3.9.6 - -* Apply locale to QuillEditor(contents). - -## 3.9.5 - -* Fix image pasting. - -## 3.9.4 - -* Hiding dialog after selecting action for image. - -## 3.9.3 - -* Update ImageResizer for Android. - -## 3.9.2 - -* Copy image with its style. - -## 3.9.1 - -* Support resizing image. - -## 3.9.0 - -* Image menu options for copy/remove. - -## 3.8.8 - -* Update set textEditingValue. - -## 3.8.7 - -* Fix checkbox not toggled correctly in toolbar button. - -## 3.8.6 - -* Fix cursor position changes when checking/unchecking the checkbox. - -## 3.8.5 - -* Fix \_handleDragUpdate in \_TextSelectionHandleOverlayState. - -## 3.8.4 - -* Fix link dialog layout. - -## 3.8.3 - -* Fix for errors on a non scrollable editor. - -## 3.8.2 - -* Fix certain keys not working on web when editor is a child of a scroll view. - -## 3.8.1 - -* Refactor \_QuillEditorState to QuillEditorState. - -## 3.8.0 - -* Support pasting with format. - -## 3.7.3 - -* Fix selection overlay for collapsed selection. - -## 3.7.2 - -* Reverted Embed toPlainText change. - -## 3.7.1 - -* Change Embed toPlainText to be empty string. - -## 3.7.0 - -* Replace Toolbar showHistory group with individual showRedo and showUndo. - -## 3.6.5 - -* Update Link dialogue for image/video. - -## 3.6.4 - -* Link dialogue TextInputType.multiline. - -## 3.6.3 - -* Bug fix for link button text selection. - -## 3.6.2 - -* Improve link button. - -## 3.6.1 - -* Remove SnackBar 'What is entered is not a link'. - -## 3.6.0 - -* Allow link button to enter text. - -## 3.5.3 - -* Change link button behavior. - -## 3.5.2 - -* Bug fix for embed. - -## 3.5.1 - -* Bug fix for platform util. - -## 3.5.0 - -* Removed redundant classes. - -## 3.4.4 - -* Add more translations. - -## 3.4.3 - -* Preset link from attributes. - -## 3.4.2 - -* Fix launch link edit mode. - -## 3.4.1 - -* Placeholder effective in scrollable. - -## 3.4.0 - -* Option to save image in read-only mode. - -## 3.3.1 - -* Pass any specified key in QuillEditor constructor to super. - -## 3.3.0 - -* Fixed Style toggle issue. - -## 3.2.1 - -* Added new translations. - -## 3.2.0 - -* Support multiple links insertion on the go. - -## 3.1.1 - -* Add selection completed callback. - -## 3.1.0 - -* Fixed image ontap functionality. - -## 3.0.4 - -* Add maxContentWidth constraint to editor. - -## 3.0.3 - -* Do not show caret on screen when the editor is not focused. - -## 3.0.2 - -* Fix launch link for read-only mode. - -## 3.0.1 - -* Handle null value of Attribute.link. - -## 3.0.0 - -* Launch link improvements. -* Removed QuillSimpleViewer. - -## 2.5.2 - -* Skip image when pasting. - -## 2.5.1 - -* Bug fix for Desktop `Shift` + `Click` support. - -## 2.5.0 - -* Update checkbox list. - -## 2.4.1 - -* Desktop selection improvements. - -## 2.4.0 - -* Improve inline code style. - -## 2.3.3 - -* Improves selection rects to have consistent height regardless of individual segment text styles. - -## 2.3.2 - -* Allow disabling floating cursor. - -## 2.3.1 - -* Preserve last newline character on delete. - -## 2.3.0 - -* Massive changes to support flutter 2.8. - -## 2.2.2 - -* iOS - floating cursor. - -## 2.2.1 - -* Bug fix for imports supporting flutter 2.8. - -## 2.2.0 - -* Support flutter 2.8. - -## 2.1.1 - -* Add methods of clearing editor and moving cursor. - -## 2.1.0 - -* Add delete handler. - -## 2.0.23 - -* Support custom replaceText handler. - -## 2.0.22 - -* Fix attribute compare and fix font size parsing. - -## 2.0.21 - -* Handle click on embed object. - -## 2.0.20 - -* Improved UX/UI of Image widget. - -## 2.0.19 - -* When uploading a video, applying indicator. - -## 2.0.18 - -* Make toolbar dividers optional. - -## 2.0.17 - -* Allow alignment of the toolbar icons to match WrapAlignment. - -## 2.0.16 - -* Add hide / show alignment buttons. - -## 2.0.15 - -* Implement change cursor to SystemMouseCursors.click when hovering a link styled text. - -## 2.0.14 - -* Enable customize the checkbox widget using DefaultListBlockStyle style. - -## 2.0.13 - -* Improve the scrolling performance by reducing the repaint areas. - -## 2.0.12 - -* Fix the selection effect can't be seen as the textLine with background color. - -## 2.0.11 - -* Fix visibility of text selection handlers on scroll. - -## 2.0.10 - -* cursorConnt.color notify the text_line to repaint if it was disposed. - -## 2.0.9 - -* Improve UX when trying to add a link. - -## 2.0.8 - -* Adding translations to the toolbar. - -## 2.0.7 - -* Added theming options for toolbar icons and LinkDialog. - -## 2.0.6 - -* Avoid runtime error when placed inside TabBarView. - -## 2.0.5 - -* Support inline code formatting. - -## 2.0.4 - -* Enable history shortcuts for desktop. - -## 2.0.3 - -* Fix cursor when line contains image. - -## 2.0.2 - -* Address KeyboardListener class name conflict. - -## 2.0.1 - -* Upgrade flutter_colorpicker to 0.5.0. - -## 2.0.0 - -* Text Alignment functions + Block Format standards. - -## 1.9.6 - -* Support putting QuillEditor inside a Scrollable view. - -## 1.9.5 - -* Skip image when pasting. - -## 1.9.4 - -* Bug fix for cursor position when tapping at the end of line with image(s). - -## 1.9.3 - -* Bug fix when line only contains one image. - -## 1.9.2 - -* Support for building custom inline styles. - -## 1.9.1 - -* Cursor jumps to the most appropriate offset to display selection. - -## 1.9.0 - -* Support inline image. - -## 1.8.3 - -* Updated quill_delta. - -## 1.8.2 - -* Support mobile image alignment. - -## 1.8.1 - -* Support mobile custom size image. - -## 1.8.0 - -* Support entering link for image/video. - -## 1.7.3 - -* Bumps photo_view version. - -## 1.7.2 - -* Fix static analysis error. - -## 1.7.1 - -* Support Youtube video. - -## 1.7.0 - -* Support video. - -## 1.6.4 - -* Bug fix for clear format button. - -## 1.6.3 - -* Fixed dragging right handle scrolling issue. - -## 1.6.2 - -* Fixed the position of the selection status drag handle. - -## 1.6.1 - -* Upgrade image_picker and flutter_colorpicker. - -## 1.6.0 - -* Support Multi Row Toolbar. - -## 1.5.0 - -* Remove file_picker dependency. - -## 1.4.1 - -* Remove filesystem_picker dependency. - -## 1.4.0 - -* Remove path_provider dependency. - -## 1.3.4 - -* Add option to paintCursorAboveText. - -## 1.3.3 - -* Upgrade file_picker version. - -## 1.3.2 - -* Fix copy/paste bug. - -## 1.3.1 - -* New logo. - -## 1.3.0 - -* Support flutter 2.2.0. - -## 1.2.2 - -* Checkbox supports tapping. - -## 1.2.1 - -* Indented position not holding while editing. - -## 1.2.0 - -* Fix image button cancel causes crash. - -## 1.1.8 - -* Fix height of empty line bug. - -## 1.1.7 - -* Fix text selection in read-only mode. - -## 1.1.6 - -* Remove universal_html dependency. - -## 1.1.5 - -* Enable "Select", "Select All" and "Copy" in read-only mode. - -## 1.1.4 - -* Fix text selection issue. - -## 1.1.3 - -* Update example folder. - -## 1.1.2 - -* Add pedantic. - -## 1.1.1 - -* Base64 image support. - -## 1.1.0 - -* Support null safety. - -## 1.0.9 - -* Web support for raw editor and keyboard listener. - -## 1.0.8 - -* Support token attribute. - -## 1.0.7 - -* Fix crash on web (dart:io). - -## 1.0.6 - -* Add desktop support WINDOWS, MACOS and LINUX. - -## 1.0.5 - -* Bug fix: Can not insert newline when Bold is toggled ON. - -## 1.0.4 - -* Upgrade photo_view to ^0.11.0. - -## 1.0.3 - -* Fix issue that text is not displayed while typing WEB. - -## 1.0.2 - -* Update toolbar in sample home page. - -## 1.0.1 - -* Fix static analysis errors. - -## 1.0.0 - -* Support flutter 2.0. - -## 1.0.0-dev.2 - -* Improve link handling for tel, mailto and etc. - -## 1.0.0-dev.1 - -* Upgrade prerelease SDK & Bump for master. - -## 0.3.5 - -* Fix for cursor focus issues when keyboard is on. - -## 0.3.4 - -* Improve link handling for tel, mailto and etc. - -## 0.3.3 - -* More fix on cursor focus issue when keyboard is on. - -## 0.3.2 - -* Fix cursor focus issue when keyboard is on. - -## 0.3.1 - -* cursor focus when keyboard is on. - -## 0.3.0 - -* Line Height calculated based on font size. - -## 0.2.12 - -* Support placeholder. - -## 0.2.11 - -* Fix static analysis error. - -## 0.2.10 - -* Update TextInputConfiguration autocorrect to true in stable branch. - -## 0.2.9 - -* Update TextInputConfiguration autocorrect to true. - -## 0.2.8 - -* Support display local image besides network image in stable branch. - -## 0.2.7 - -* Support display local image besides network image. - -## 0.2.6 - -* Fix cursor after pasting. - -## 0.2.5 - -* Toggle text/background color button in toolbar. - -## 0.2.4 - -* Support the use of custom icon size in toolbar. - -## 0.2.3 - -* Support custom styles and image on local device storage without uploading. - -## 0.2.2 - -* Update git repo. - -## 0.2.1 - -* Fix static analysis error. - -## 0.2.0 - -* Add checked/unchecked list button in toolbar. - -## 0.1.8 - -* Support font and size attributes. - -## 0.1.7 - -* Support checked/unchecked list. - -## 0.1.6 - -* Fix getExtentEndpointForSelection. - -## 0.1.5 - -* Support text alignment. - -## 0.1.4 - -* Handle url with trailing spaces. - -## 0.1.3 - -* Handle cursor position change when undo/redo. - -## 0.1.2 - -* Handle more text colors. - -## 0.1.1 - -* Fix cursor issue when undo. - -## 0.1.0 - -* Fix insert image. - -## 0.0.9 - -* Handle rgba color. - -## 0.0.8 - -* Fix launching url. - -## 0.0.7 - -* Handle multiple image inserts. - -## 0.0.6 - -* More toolbar functionality. - -## 0.0.5 - -* Update example. - -## 0.0.4 - -* Update example. - -## 0.0.3 - -* Update home page meta data. - -## 0.0.2 - -* Support image upload and launch url in read-only mode. - -## 0.0.1 - -* Rich text editor based on Quill Delta. - diff --git a/quill_native_bridge/LICENSE b/quill_native_bridge/LICENSE deleted file mode 100644 index e7ff73e1b..000000000 --- a/quill_native_bridge/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Flutter Quill project and open source contributors. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/quill_native_bridge/README.md b/quill_native_bridge/README.md deleted file mode 100644 index 216dfc41e..000000000 --- a/quill_native_bridge/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# 🪶 Quill Native Bridge - -An internal plugin for [`flutter_quill`](https://pub.dev/packages/flutter_quill) package to access platform-specific APIs. - -> [!NOTE] -> **Internal Use Only**: Exclusively for `flutter_quill`. Breaking changes may occur. \ No newline at end of file diff --git a/quill_native_bridge/analysis_options.yaml b/quill_native_bridge/analysis_options.yaml deleted file mode 100644 index b6065426f..000000000 --- a/quill_native_bridge/analysis_options.yaml +++ /dev/null @@ -1,32 +0,0 @@ -include: package:flutter_lints/flutter.yaml - -linter: - rules: - always_declare_return_types: true - always_put_required_named_parameters_first: true - annotate_overrides: true - avoid_empty_else: true - avoid_escaping_inner_quotes: true - avoid_print: true - avoid_types_on_closure_parameters: true - avoid_void_async: true - cascade_invocations: true - directives_ordering: true - omit_local_variable_types: true - prefer_const_constructors: true - prefer_const_constructors_in_immutables: true - prefer_const_declarations: true - prefer_final_fields: true - prefer_final_in_for_each: true - prefer_final_locals: true - prefer_initializing_formals: true - prefer_int_literals: true - prefer_interpolation_to_compose_strings: true - prefer_relative_imports: true - prefer_single_quotes: true - sort_constructors_first: true - sort_unnamed_constructors_first: true - unnecessary_lambdas: true - unnecessary_parenthesis: true - unnecessary_string_interpolations: true - avoid_web_libraries_in_flutter: true diff --git a/quill_native_bridge/ios/.gitignore b/quill_native_bridge/ios/.gitignore deleted file mode 100644 index 034771fc9..000000000 --- a/quill_native_bridge/ios/.gitignore +++ /dev/null @@ -1,38 +0,0 @@ -.idea/ -.vagrant/ -.sconsign.dblite -.svn/ - -.DS_Store -*.swp -profile - -DerivedData/ -build/ -GeneratedPluginRegistrant.h -GeneratedPluginRegistrant.m - -.generated/ - -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - -xcuserdata - -*.moved-aside - -*.pyc -*sync/ -Icon? -.tags* - -/Flutter/Generated.xcconfig -/Flutter/ephemeral/ -/Flutter/flutter_export_environment.sh diff --git a/quill_native_bridge/ios/Assets/.gitkeep b/quill_native_bridge/ios/Assets/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/quill_native_bridge/ios/Classes/QuillNativeBridgePlugin.swift b/quill_native_bridge/ios/Classes/QuillNativeBridgePlugin.swift deleted file mode 100644 index e5e9997ab..000000000 --- a/quill_native_bridge/ios/Classes/QuillNativeBridgePlugin.swift +++ /dev/null @@ -1,23 +0,0 @@ -import Flutter -import UIKit - -public class QuillNativeBridgePlugin: NSObject, FlutterPlugin { - public static func register(with registrar: FlutterPluginRegistrar) { - let channel = FlutterMethodChannel(name: "quill_native_bridge", binaryMessenger: registrar.messenger()) - let instance = QuillNativeBridgePlugin() - registrar.addMethodCallDelegate(instance, channel: channel) - } - - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - switch call.method { - case "isIOSSimulator": - #if targetEnvironment(simulator) - result(true) - #else - result(false) - #endif - default: - result(FlutterMethodNotImplemented) - } - } -} diff --git a/quill_native_bridge/ios/quill_native_bridge.podspec b/quill_native_bridge/ios/quill_native_bridge.podspec deleted file mode 100644 index 3e59e619e..000000000 --- a/quill_native_bridge/ios/quill_native_bridge.podspec +++ /dev/null @@ -1,29 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint quill_native_bridge.podspec` to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'quill_native_bridge' - s.version = '0.0.1' - s.summary = 'A plugin for flutter_quill' - s.description = <<-DESC -An internal plugin for flutter_quill package to access platform-specific APIs. - DESC - s.homepage = 'https://github.com/singerdmx/flutter-quill' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Quill' => 'https://github.com/singerdmx/flutter-quill' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.dependency 'Flutter' - s.platform = :ios, '12.0' - - # Flutter.framework does not contain a i386 slice. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } - s.swift_version = '5.0' - - # If your plugin requires a privacy manifest, for example if it uses any - # required reason APIs, update the PrivacyInfo.xcprivacy file to describe your - # plugin's privacy impact, and then uncomment this line. For more information, - # see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files - # s.resource_bundles = {'quill_native_bridge_privacy' => ['Resources/PrivacyInfo.xcprivacy']} -end diff --git a/quill_native_bridge/lib/quill_native_bridge.dart b/quill_native_bridge/lib/quill_native_bridge.dart deleted file mode 100644 index a14a6d271..000000000 --- a/quill_native_bridge/lib/quill_native_bridge.dart +++ /dev/null @@ -1,14 +0,0 @@ -library; - -import 'src/quill_native_bridge_platform_interface.dart'; - -class QuillNativeBridge { - QuillNativeBridge._(); - - /// Check if the app is running on [iOS Simulator](https://developer.apple.com/documentation/xcode/running-your-app-in-simulator-or-on-a-device). - /// - /// This function should only be called when [defaultTargetPlatform] - /// is [TargetPlatform.iOS] and [kIsWeb] is `false`. - static Future isIOSSimulator() => - QuillNativeBridgePlatform.instance.isIOSSimulator(); -} diff --git a/quill_native_bridge/lib/src/quill_native_bridge_method_channel.dart b/quill_native_bridge/lib/src/quill_native_bridge_method_channel.dart deleted file mode 100644 index e4475cbc5..000000000 --- a/quill_native_bridge/lib/src/quill_native_bridge_method_channel.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; - -import 'quill_native_bridge_platform_interface.dart'; - -class MethodChannelQuillNativeBridge implements QuillNativeBridgePlatform { - @visibleForTesting - final methodChannel = const MethodChannel('quill_native_bridge'); - - @override - Future isIOSSimulator() async { - assert(() { - if (kIsWeb || defaultTargetPlatform != TargetPlatform.iOS) { - throw FlutterError( - 'isIOSSimulator() method should be called only on iOS.', - ); - } - return true; - }()); - final isSimulator = - await methodChannel.invokeMethod('isIOSSimulator'); - assert(() { - if (isSimulator == null) { - throw FlutterError( - 'isSimulator should not be null.', - ); - } - return true; - }()); - return isSimulator ?? false; - } -} diff --git a/quill_native_bridge/lib/src/quill_native_bridge_platform_interface.dart b/quill_native_bridge/lib/src/quill_native_bridge_platform_interface.dart deleted file mode 100644 index 406c530e3..000000000 --- a/quill_native_bridge/lib/src/quill_native_bridge_platform_interface.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; - -import 'quill_native_bridge_method_channel.dart'; - -abstract class QuillNativeBridgePlatform extends PlatformInterface { - /// Constructs a QuillNativeBridgePlatform. - QuillNativeBridgePlatform() : super(token: _token); - - /// Avoid using `const` when creating the `Object` for `_token` - static final Object _token = Object(); - - static QuillNativeBridgePlatform _instance = MethodChannelQuillNativeBridge(); - - /// The default instance of [QuillNativeBridgePlatform] to use. - /// - /// Defaults to [MethodChannelQuillNativeBridge]. - static QuillNativeBridgePlatform get instance => _instance; - - /// Platform-specific implementations should set this with their own - /// platform-specific class that extends [QuillNativeBridgePlatform] when - /// they register themselves. - static set instance(QuillNativeBridgePlatform instance) { - PlatformInterface.verify(instance, _token); - _instance = instance; - } - - /// Check if the app is running on [iOS Simulator](https://developer.apple.com/documentation/xcode/running-your-app-in-simulator-or-on-a-device). - Future isIOSSimulator() { - throw UnimplementedError('isIOSSimulator() has not been implemented.'); - } -} diff --git a/quill_native_bridge/pubspec.yaml b/quill_native_bridge/pubspec.yaml deleted file mode 100644 index da87139e3..000000000 --- a/quill_native_bridge/pubspec.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: quill_native_bridge -description: "An internal plugin for flutter_quill package to access platform-specific APIs" -version: 10.7.3 -homepage: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ -repository: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ -issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ -documentation: https://github.com/singerdmx/flutter-quill/tree/master/quill_native_bridge/ - -environment: - sdk: ^3.5.1 - flutter: '>=3.3.0' - -dependencies: - flutter: - sdk: flutter - plugin_platform_interface: ^2.1.8 - -dev_dependencies: - flutter_test: - sdk: flutter - flutter_lints: ^5.0.0 - -flutter: - plugin: - platforms: - ios: - pluginClass: QuillNativeBridgePlugin \ No newline at end of file diff --git a/quill_native_bridge/test/quill_native_bridge_method_channel_test.dart b/quill_native_bridge/test/quill_native_bridge_method_channel_test.dart deleted file mode 100644 index d0e1bbd46..000000000 --- a/quill_native_bridge/test/quill_native_bridge_method_channel_test.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:quill_native_bridge/src/quill_native_bridge_method_channel.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - final platform = MethodChannelQuillNativeBridge(); - const channel = MethodChannel('quill_native_bridge'); - - setUp(() { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler( - channel, - (methodCall) async { - return false; - }, - ); - }); - - tearDown(() { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(channel, null); - }); - - test('isIOSSimulator', () async { - debugDefaultTargetPlatformOverride = TargetPlatform.iOS; - expect(await platform.isIOSSimulator(), false); - }); -} diff --git a/quill_native_bridge/test/quill_native_bridge_test.dart b/quill_native_bridge/test/quill_native_bridge_test.dart deleted file mode 100644 index 5ad8c969e..000000000 --- a/quill_native_bridge/test/quill_native_bridge_test.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'package:quill_native_bridge/quill_native_bridge.dart'; -import 'package:quill_native_bridge/src/quill_native_bridge_method_channel.dart'; -import 'package:quill_native_bridge/src/quill_native_bridge_platform_interface.dart'; - -class MockQuillNativeBridgePlatform - with MockPlatformInterfaceMixin - implements QuillNativeBridgePlatform { - @override - Future isIOSSimulator() async => false; -} - -void main() { - final initialPlatform = QuillNativeBridgePlatform.instance; - - test('$MethodChannelQuillNativeBridge is the default instance', () { - expect(initialPlatform, isInstanceOf()); - }); - - test('isIOSSimulator', () async { - final fakePlatform = MockQuillNativeBridgePlatform(); - QuillNativeBridgePlatform.instance = fakePlatform; - - debugDefaultTargetPlatformOverride = TargetPlatform.iOS; - expect(await QuillNativeBridge.isIOSSimulator(), false); - }); -} From 48cdbb49961cac1d83fe160966b8ae53d39af0c5 Mon Sep 17 00:00:00 2001 From: EchoEllet Date: Thu, 17 Oct 2024 00:00:14 +0000 Subject: [PATCH 077/113] chore(version): update to version 10.8.3-dev.0 --- CHANGELOG.md | 9 +++++++++ CHANGELOG_DATA.json | 1 + example/macos/Flutter/GeneratedPluginRegistrant.swift | 2 +- flutter_quill_extensions/CHANGELOG.md | 9 +++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 9 +++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 8 files changed, 32 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a816d0add..ac5d1dbb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. +## 10.8.3-dev.0 + +A non-pre-release version with this change will be published soon. + +* feat: Use quill_native_bridge as default impl in DefaultClipboardService, fix related bugs in the extensions package by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2230 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3-dev.0 + ## 10.8.2 * Fixed minor typo in Hungarian (hu) localization by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2307 diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index 3e57b98c9..673e2cc7e 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.8.3-dev.0": "A non-pre-release version with this change will be published soon.\r\n\r\n* feat: Use quill_native_bridge as default impl in DefaultClipboardService, fix related bugs in the extensions package by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2230\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3-dev.0", "10.8.2": "* Fixed minor typo in Hungarian (hu) localization by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2307\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.1...v10.8.2", "10.8.1": "- This release fixes the compilation issue when building the project with [Flutter/Wasm](https://docs.flutter.dev/platform-integration/web/wasm) target on the web. Also, update the conditional import check to avoid using `dart.library.html`:\r\n\r\n ```dart\r\n import 'web/quill_controller_web_stub.dart'\r\n if (dart.library.html) 'web/quill_controller_web_real.dart';\r\n ```\r\n \r\n To fix critical bugs that prevent using the editor on Wasm.\r\n \r\n > Flutter/Wasm is stable as of [Flutter 3.22](https://medium.com/flutter/whats-new-in-flutter-3-22-fbde6c164fe3) though it's likely that you might experience some issues when using this new target, if you experienced any issues related to Wasm support related to Flutter Quill, feel free to [open an issue](https://github.com/singerdmx/flutter-quill/issues).\r\n \r\n Issue #1889 is fixed by temporarily replacing the plugin [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) with [flutter_keyboard_visibility_temp_fork](https://pub.dev/packages/flutter_keyboard_visibility_temp_fork) since `flutter_keyboard_visibility` depend on `dart:html`. Also updated the `compileSdkVersion` to `34` instead of `31` as a workaround to [Flutter #63533](https://github.com/flutter/flutter/issues/63533).\r\n\r\n- Support for Hungarian (hu) localization was added by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2291.\r\n- [dart_quill_delta](https://pub.dev/packages/dart_quill_delta/) has been moved to [FlutterQuill/dart-quill-delta](https://github.com/FlutterQuill/dart-quill-delta) (outside of this repo) and they have separated version now.\r\n\r\n\r\n## New Contributors\r\n* @G-Greg made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2291\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.0...v10.8.1", "10.8.0": "> [!CAUTION]\r\n> This release can be breaking change for `flutter_quill_extensions` users as it remove the built-in support for loading YouTube videos\r\n\r\nIf you're using [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) then this release, can be a breaking change for you if you load videos in the editor and expect YouTube videos to be supported, [youtube_player_flutter](https://pub.dev/packages/youtube_player_flutter) and [flutter_inappwebview](https://pub.dev/packages/flutter_inappwebview) are no longer dependencies of the extensions package, which are used to support loading YouTube Iframe videos on non-web platforms, more details about the discussion and reasons in [#2286](https://github.com/singerdmx/flutter-quill/pull/2286) and [#2284](https://github.com/singerdmx/flutter-quill/issues/2284).\r\n\r\nWe have added an experimental property that gives you more flexibility and control about the implementation you want to use for loading videos.\r\n\r\n> [!WARNING]\r\n> It's likely to experience some common issues while implementing this feature, especially on desktop platforms as the support for [flutter_inappwebview_windows](https://pub.dev/packages/flutter_inappwebview_windows) and [flutter_inappwebview_macos](https://pub.dev/packages/flutter_inappwebview_macos) before 2 days. Some of the issues are in the Flutter Quill editor.\r\n\r\nIf you want loading YouTube videos to be a feature again with the latest version of Flutter Quill, you can use an existing plugin or package, or implement your own solution. For example, you might use [`youtube_video_player`](https://pub.dev/packages/youtube_video_player) or [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter), which was previously used in [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions).\r\n\r\nHere’s an example setup using `youtube_player_flutter`:\r\n\r\n```shell\r\nflutter pub add youtube_player_flutter\r\n```\r\n\r\nExample widget configuration:\r\n\r\n```dart\r\nimport 'package:flutter/material.dart';\r\nimport 'package:youtube_player_flutter/youtube_player_flutter.dart';\r\n\r\nclass YoutubeVideoPlayer extends StatefulWidget {\r\n const YoutubeVideoPlayer({required this.videoUrl, super.key});\r\n\r\n final String videoUrl;\r\n\r\n @override\r\n State createState() => _YoutubeVideoPlayerState();\r\n}\r\n\r\nclass _YoutubeVideoPlayerState extends State {\r\n late final YoutubePlayerController _youtubePlayerController;\r\n @override\r\n void initState() {\r\n super.initState();\r\n _youtubePlayerController = YoutubePlayerController(\r\n initialVideoId: YoutubePlayer.convertUrlToId(widget.videoUrl) ??\r\n (throw StateError('Expect a valid video URL')),\r\n flags: const YoutubePlayerFlags(\r\n autoPlay: true,\r\n mute: true,\r\n ),\r\n );\r\n }\r\n\r\n @override\r\n Widget build(BuildContext context) {\r\n return YoutubePlayer(\r\n controller: _youtubePlayerController,\r\n showVideoProgressIndicator: true,\r\n );\r\n }\r\n\r\n @override\r\n void dispose() {\r\n _youtubePlayerController.dispose();\r\n super.dispose();\r\n }\r\n}\r\n\r\n```\r\n\r\nThen, integrate it with `QuillEditorVideoEmbedConfigurations`\r\n\r\n```dart\r\nFlutterQuillEmbeds.editorBuilders(\r\n videoEmbedConfigurations: QuillEditorVideoEmbedConfigurations(\r\n customVideoBuilder: (videoUrl, readOnly) {\r\n // Example: Check for YouTube Video URL and return your\r\n // YouTube video widget here.\r\n bool isYouTubeUrl(String videoUrl) {\r\n try {\r\n final uri = Uri.parse(videoUrl);\r\n return uri.host == 'www.youtube.com' ||\r\n uri.host == 'youtube.com' ||\r\n uri.host == 'youtu.be' ||\r\n uri.host == 'www.youtu.be';\r\n } catch (_) {\r\n return false;\r\n }\r\n }\r\n\r\n if (isYouTubeUrl(videoUrl)) {\r\n return YoutubeVideoPlayer(\r\n videoUrl: videoUrl,\r\n );\r\n }\r\n\r\n // Return null to fallback to the default logic\r\n return null;\r\n },\r\n ignoreYouTubeSupport: true,\r\n ),\r\n);\r\n```\r\n\r\n> [!NOTE]\r\n> This example illustrates a basic approach, additional adjustments might be necessary to meet your specific needs. YouTube video support is no longer included in this project. Keep in mind that `customVideoBuilder` is experimental and can change without being considered as breaking change. More details in [breaking changes](https://github.com/singerdmx/flutter-quill#-breaking-changes) section.\r\n\r\n[`super_clipboard`](https://pub.dev/packages/super_clipboard) will also no longer a dependency of `flutter_quill_extensions` once [PR #2230](https://github.com/singerdmx/flutter-quill/pull/2230) is ready.\r\n\r\nWe're looking forward to your feedback.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.7.7...v10.8.0", diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index 988945165..10abb57dc 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -13,7 +13,7 @@ import irondash_engine_context import path_provider_foundation import quill_native_bridge_macos import share_plus -import sqflite +import sqflite_darwin import super_native_extensions import url_launcher_macos import video_player_avfoundation diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index a816d0add..ac5d1dbb1 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. +## 10.8.3-dev.0 + +A non-pre-release version with this change will be published soon. + +* feat: Use quill_native_bridge as default impl in DefaultClipboardService, fix related bugs in the extensions package by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2230 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3-dev.0 + ## 10.8.2 * Fixed minor typo in Hungarian (hu) localization by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2307 diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 70046cc92..0a78ef68e 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.8.2 +version: 10.8.3-dev.0 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index a816d0add..ac5d1dbb1 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. +## 10.8.3-dev.0 + +A non-pre-release version with this change will be published soon. + +* feat: Use quill_native_bridge as default impl in DefaultClipboardService, fix related bugs in the extensions package by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2230 + + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3-dev.0 + ## 10.8.2 * Fixed minor typo in Hungarian (hu) localization by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2307 diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 83f1960b6..7c6df6c7b 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.8.2 +version: 10.8.3-dev.0 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 98a900959..2227611ae 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.8.2 +version: 10.8.3-dev.0 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 57610210f438e90e0f7b0026fb9a04764dcb32cc Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 17 Oct 2024 03:07:52 +0300 Subject: [PATCH 078/113] chore(deps): update minimum version of flutter_quill in flutter_quill_extensions, remove pubspec_overrides, part of https://github.com/singerdmx/flutter-quill/pull/2230 --- flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_extensions/pubspec_overrides.yaml | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 flutter_quill_extensions/pubspec_overrides.yaml diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 0a78ef68e..9519b8989 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -35,7 +35,7 @@ dependencies: universal_html: ^2.2.4 cross_file: ^0.3.3+6 - flutter_quill: ^10.7.2 + flutter_quill: ^10.8.3-dev.0 photo_view: ^0.15.0 # TODO: Remove youtube_explode_dart youtube_explode_dart: ^2.2.1 diff --git a/flutter_quill_extensions/pubspec_overrides.yaml b/flutter_quill_extensions/pubspec_overrides.yaml deleted file mode 100644 index b4f64788e..000000000 --- a/flutter_quill_extensions/pubspec_overrides.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# TODO: Remove this file completely once https://github.com/singerdmx/flutter-quill/pull/2230 is complete before publishing -dependency_overrides: - flutter_quill: - path: ../ \ No newline at end of file From a18ab286bd0a7751117f1dfec7bc6457c645f2e9 Mon Sep 17 00:00:00 2001 From: EchoEllet Date: Thu, 17 Oct 2024 00:16:07 +0000 Subject: [PATCH 079/113] chore(version): update to version 10.8.3 --- CHANGELOG.md | 8 ++++++++ CHANGELOG_DATA.json | 1 + flutter_quill_extensions/CHANGELOG.md | 8 ++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 8 ++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 7 files changed, 28 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac5d1dbb1..f18e772de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.8.3 + +This release is identical to [v10.8.3-dev.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.3-dev.0), mainly published to bump the minimum version of [flutter_quill](https://pub.dev/packages/flutter_quill) in [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) and to publish [quill-super-clipboard](https://github.com/FlutterQuill/quill-super-clipboard/). + +A new identical release `10.9.0` will be published soon with a release description. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3 + ## 10.8.3-dev.0 A non-pre-release version with this change will be published soon. diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index 673e2cc7e..641d27b79 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.8.3": "This release is identical to [v10.8.3-dev.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.3-dev.0), mainly published to bump the minimum version of [flutter_quill](https://pub.dev/packages/flutter_quill) in [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) and to publish [quill-super-clipboard](https://github.com/FlutterQuill/quill-super-clipboard/).\r\n\r\nA new identical release `10.9.0` will be published soon with a release description.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3", "10.8.3-dev.0": "A non-pre-release version with this change will be published soon.\r\n\r\n* feat: Use quill_native_bridge as default impl in DefaultClipboardService, fix related bugs in the extensions package by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2230\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3-dev.0", "10.8.2": "* Fixed minor typo in Hungarian (hu) localization by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2307\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.1...v10.8.2", "10.8.1": "- This release fixes the compilation issue when building the project with [Flutter/Wasm](https://docs.flutter.dev/platform-integration/web/wasm) target on the web. Also, update the conditional import check to avoid using `dart.library.html`:\r\n\r\n ```dart\r\n import 'web/quill_controller_web_stub.dart'\r\n if (dart.library.html) 'web/quill_controller_web_real.dart';\r\n ```\r\n \r\n To fix critical bugs that prevent using the editor on Wasm.\r\n \r\n > Flutter/Wasm is stable as of [Flutter 3.22](https://medium.com/flutter/whats-new-in-flutter-3-22-fbde6c164fe3) though it's likely that you might experience some issues when using this new target, if you experienced any issues related to Wasm support related to Flutter Quill, feel free to [open an issue](https://github.com/singerdmx/flutter-quill/issues).\r\n \r\n Issue #1889 is fixed by temporarily replacing the plugin [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) with [flutter_keyboard_visibility_temp_fork](https://pub.dev/packages/flutter_keyboard_visibility_temp_fork) since `flutter_keyboard_visibility` depend on `dart:html`. Also updated the `compileSdkVersion` to `34` instead of `31` as a workaround to [Flutter #63533](https://github.com/flutter/flutter/issues/63533).\r\n\r\n- Support for Hungarian (hu) localization was added by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2291.\r\n- [dart_quill_delta](https://pub.dev/packages/dart_quill_delta/) has been moved to [FlutterQuill/dart-quill-delta](https://github.com/FlutterQuill/dart-quill-delta) (outside of this repo) and they have separated version now.\r\n\r\n\r\n## New Contributors\r\n* @G-Greg made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2291\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.0...v10.8.1", diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index ac5d1dbb1..f18e772de 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.8.3 + +This release is identical to [v10.8.3-dev.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.3-dev.0), mainly published to bump the minimum version of [flutter_quill](https://pub.dev/packages/flutter_quill) in [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) and to publish [quill-super-clipboard](https://github.com/FlutterQuill/quill-super-clipboard/). + +A new identical release `10.9.0` will be published soon with a release description. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3 + ## 10.8.3-dev.0 A non-pre-release version with this change will be published soon. diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 9519b8989..a8a015364 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.8.3-dev.0 +version: 10.8.3 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index ac5d1dbb1..f18e772de 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. +## 10.8.3 + +This release is identical to [v10.8.3-dev.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.3-dev.0), mainly published to bump the minimum version of [flutter_quill](https://pub.dev/packages/flutter_quill) in [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) and to publish [quill-super-clipboard](https://github.com/FlutterQuill/quill-super-clipboard/). + +A new identical release `10.9.0` will be published soon with a release description. + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3 + ## 10.8.3-dev.0 A non-pre-release version with this change will be published soon. diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 7c6df6c7b..6466d791a 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.8.3-dev.0 +version: 10.8.3 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 2227611ae..57de703a8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.8.3-dev.0 +version: 10.8.3 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 071edabc3dc82674bd87ad664105283171f7ffd2 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 17 Oct 2024 03:22:05 +0300 Subject: [PATCH 080/113] chore(deps): bump minimum flutter_quill to 10.8.3 in flutter_quill_extensions --- flutter_quill_extensions/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index a8a015364..37b2dcdc0 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -35,7 +35,7 @@ dependencies: universal_html: ^2.2.4 cross_file: ^0.3.3+6 - flutter_quill: ^10.8.3-dev.0 + flutter_quill: ^10.8.3 photo_view: ^0.15.0 # TODO: Remove youtube_explode_dart youtube_explode_dart: ^2.2.1 From f2220cc609a25e836e47d71f6c3fb1365d8fc635 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 17 Oct 2024 08:07:39 +0300 Subject: [PATCH 081/113] chore(deps): update min version of quill_native_bridge --- example/macos/Podfile.lock | 16 ++++++++-------- pubspec.yaml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index d9fe20ac9..3df1b3747 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -18,7 +18,7 @@ PODS: - FlutterMacOS - share_plus (0.0.1): - FlutterMacOS - - sqflite (0.0.3): + - sqflite_darwin (0.0.4): - Flutter - FlutterMacOS - super_native_extensions (0.0.1): @@ -39,7 +39,7 @@ DEPENDENCIES: - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - quill_native_bridge_macos (from `Flutter/ephemeral/.symlinks/plugins/quill_native_bridge_macos/macos`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`) + - sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`) - super_native_extensions (from `Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - video_player_avfoundation (from `Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin`) @@ -63,8 +63,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/quill_native_bridge_macos/macos share_plus: :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos - sqflite: - :path: Flutter/ephemeral/.symlinks/plugins/sqflite/darwin + sqflite_darwin: + :path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin super_native_extensions: :path: Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos url_launcher_macos: @@ -75,16 +75,16 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898 device_info_plus: ce1b7762849d3ec103d0e0517299f2db7ad60720 - file_selector_macos: 54fdab7caa3ac3fc43c9fac4d7d8d231277f8cf2 + file_selector_macos: cc3858c981fe6889f364731200d6232dac1d812d FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 gal: 61e868295d28fe67ffa297fae6dacebf56fd53e1 irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 quill_native_bridge_macos: f90985c5269ac7ba84d933605b463d96e5f544fe - share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf - sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec + share_plus: a182a58e04e51647c0481aadabbc4de44b3a2bce + sqflite_darwin: a553b1fd6fe66f53bbb0fe5b4f5bab93f08d7a13 super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3 - url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399 + url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 PODFILE CHECKSUM: 7159dd71cf9f57a5669bb2dee7a5030dbcc0483f diff --git a/pubspec.yaml b/pubspec.yaml index 57de703a8..670400444 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,7 +61,7 @@ dependencies: # Plugins url_launcher: ^6.2.4 flutter_keyboard_visibility_temp_fork: ^0.1.1 - quill_native_bridge: ^10.7.8 + quill_native_bridge: ^10.7.9 dev_dependencies: flutter_lints: ^5.0.0 From 62d821252c42a834567be42409c702547733cc02 Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 17 Oct 2024 08:12:45 +0300 Subject: [PATCH 082/113] fix: avoid using getClipboardFiles() if unsupported on the current platform --- .../clipboard/default_clipboard_service.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/editor_toolbar_controller_shared/clipboard/default_clipboard_service.dart b/lib/src/editor_toolbar_controller_shared/clipboard/default_clipboard_service.dart index 21db10cdd..6ce39da24 100644 --- a/lib/src/editor_toolbar_controller_shared/clipboard/default_clipboard_service.dart +++ b/lib/src/editor_toolbar_controller_shared/clipboard/default_clipboard_service.dart @@ -48,6 +48,10 @@ class DefaultClipboardService extends ClipboardService { } Future _getClipboardFile({required String fileExtension}) async { + if (!(await QuillNativeBridge.isSupported( + QuillNativeBridgeFeature.getClipboardFiles))) { + return null; + } if (kIsWeb) { // TODO: Can't read file with dart:io on the Web (See related https://github.com/FlutterQuill/quill-native-bridge/issues/6) return null; From 5ecebd2755980aa5a14c09bd4779b5317d36b85b Mon Sep 17 00:00:00 2001 From: EchoEllet Date: Thu, 17 Oct 2024 06:23:50 +0000 Subject: [PATCH 083/113] chore(version): update to version 10.8.4 --- CHANGELOG.md | 7 +++++++ CHANGELOG_DATA.json | 1 + flutter_quill_extensions/CHANGELOG.md | 7 +++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 7 +++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 7 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f18e772de..76a9cb1d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.8.4 + +- [Fixes an unhandled exception](https://github.com/singerdmx/flutter-quill/commit/8dd559b825030d29b30b32b353a08dcc13dc42b7) in case `getClipboardFiles()` wasn't supported +- [Updates min version](https://github.com/singerdmx/flutter-quill/commit/49569e47b038c5f61b7521571c102cf5ad5a0e3f) of internal dependency `quill_native_bridge` + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.3...v10.8.4 + ## 10.8.3 This release is identical to [v10.8.3-dev.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.3-dev.0), mainly published to bump the minimum version of [flutter_quill](https://pub.dev/packages/flutter_quill) in [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) and to publish [quill-super-clipboard](https://github.com/FlutterQuill/quill-super-clipboard/). diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index 641d27b79..703289855 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.8.4": "- [Fixes an unhandled exception](https://github.com/singerdmx/flutter-quill/commit/8dd559b825030d29b30b32b353a08dcc13dc42b7) in case `getClipboardFiles()` wasn't supported\r\n- [Updates min version](https://github.com/singerdmx/flutter-quill/commit/49569e47b038c5f61b7521571c102cf5ad5a0e3f) of internal dependency `quill_native_bridge`\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.3...v10.8.4", "10.8.3": "This release is identical to [v10.8.3-dev.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.3-dev.0), mainly published to bump the minimum version of [flutter_quill](https://pub.dev/packages/flutter_quill) in [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) and to publish [quill-super-clipboard](https://github.com/FlutterQuill/quill-super-clipboard/).\r\n\r\nA new identical release `10.9.0` will be published soon with a release description.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3", "10.8.3-dev.0": "A non-pre-release version with this change will be published soon.\r\n\r\n* feat: Use quill_native_bridge as default impl in DefaultClipboardService, fix related bugs in the extensions package by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2230\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3-dev.0", "10.8.2": "* Fixed minor typo in Hungarian (hu) localization by @G-Greg in https://github.com/singerdmx/flutter-quill/pull/2307\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.1...v10.8.2", diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index f18e772de..76a9cb1d5 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.8.4 + +- [Fixes an unhandled exception](https://github.com/singerdmx/flutter-quill/commit/8dd559b825030d29b30b32b353a08dcc13dc42b7) in case `getClipboardFiles()` wasn't supported +- [Updates min version](https://github.com/singerdmx/flutter-quill/commit/49569e47b038c5f61b7521571c102cf5ad5a0e3f) of internal dependency `quill_native_bridge` + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.3...v10.8.4 + ## 10.8.3 This release is identical to [v10.8.3-dev.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.3-dev.0), mainly published to bump the minimum version of [flutter_quill](https://pub.dev/packages/flutter_quill) in [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) and to publish [quill-super-clipboard](https://github.com/FlutterQuill/quill-super-clipboard/). diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 37b2dcdc0..55a2fc59e 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.8.3 +version: 10.8.4 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index f18e772de..76a9cb1d5 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## 10.8.4 + +- [Fixes an unhandled exception](https://github.com/singerdmx/flutter-quill/commit/8dd559b825030d29b30b32b353a08dcc13dc42b7) in case `getClipboardFiles()` wasn't supported +- [Updates min version](https://github.com/singerdmx/flutter-quill/commit/49569e47b038c5f61b7521571c102cf5ad5a0e3f) of internal dependency `quill_native_bridge` + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.3...v10.8.4 + ## 10.8.3 This release is identical to [v10.8.3-dev.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.3-dev.0), mainly published to bump the minimum version of [flutter_quill](https://pub.dev/packages/flutter_quill) in [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) and to publish [quill-super-clipboard](https://github.com/FlutterQuill/quill-super-clipboard/). diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 6466d791a..9e676c4fb 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.8.3 +version: 10.8.4 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 670400444..19829c413 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.8.3 +version: 10.8.4 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 002a92f84af1926b194fede98a7502365325b3fa Mon Sep 17 00:00:00 2001 From: Ellet Date: Thu, 17 Oct 2024 09:48:01 +0300 Subject: [PATCH 084/113] docs(readme): improve the note message of quill_super_clipboard and quill_native_bridge --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7ac721aa7..9b545160c 100644 --- a/README.md +++ b/README.md @@ -157,9 +157,9 @@ Create the file `your_project/android/app/src/main/res/xml/file_paths.xml` with ``` > [!NOTE] -> [super_clipboard](https://pub.dev/packages/super_clipboard) is no longer required -> in recent versions of Flutter Quill in `flutter_quill` or `flutter_quill_extensions`. -> [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge) is a plugin that provide clipboard operations functionality for `flutter_quill`. +> Starting with Flutter Quill `10.8.4`, [super_clipboard](https://pub.dev/packages/super_clipboard) is no longer required in `flutter_quill` or `flutter_quill_extensions`. +> The new default is an internal plugin, [`quill_native_bridge`](https://pub.dev/packages/quill_native_bridge). +> If you want to continue using `super_clipboard`, you can use the [quill_super_clipboard](https://pub.dev/packages/quill_super_clipboard) package (support may be discontinued). ## 🚀 Usage From 3482130fb616a9ea6f96faea1bf065a5abc0fd9d Mon Sep 17 00:00:00 2001 From: Olivier Revial Date: Tue, 22 Oct 2024 16:21:32 +0200 Subject: [PATCH 085/113] fix: allow all correct URLs to be formatted (#2328) --- lib/src/rules/insert.dart | 5 ++--- test/rules/insert_test.dart | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/lib/src/rules/insert.dart b/lib/src/rules/insert.dart index a8dafb925..851c9b806 100644 --- a/lib/src/rules/insert.dart +++ b/lib/src/rules/insert.dart @@ -343,7 +343,6 @@ class AutoFormatMultipleLinksRule extends InsertRule { /// This pattern is used to match a links within a text segment. /// /// It works for the following testing URLs: - // www.google.com // http://google.com // https://www.google.com // http://beginner.example.edu/#act @@ -364,9 +363,9 @@ class AutoFormatMultipleLinksRule extends InsertRule { // URL generator tool (https://www.randomlists.com/urls) is used. static const _oneLineLinkPattern = - r'^https?:\/\/[\w\-]+(\.[\w\-]+)*(:\d+)?(\/.*)?$'; + r'^https?:\/\/[\w\-]+(\.[\w\-]+)*(:\d+)?([\/\?#].*)?$'; static const _detectLinkPattern = - r'https?:\/\/[\w\-]+(\.[\w\-]+)*(:\d+)?(\/[^\s]*)?'; + r'https?:\/\/[\w\-]+(\.[\w\-]+)*(:\d+)?([\/\?#][^\s]*)?'; /// It requires a valid link in one link RegExp get oneLineLinkRegExp => RegExp( diff --git a/test/rules/insert_test.dart b/test/rules/insert_test.dart index 00ab5bbae..dfafa2800 100644 --- a/test/rules/insert_test.dart +++ b/test/rules/insert_test.dart @@ -286,4 +286,45 @@ void main() { reason: 'Insertion within link label updates label'); }); }); + + group('AutoFormatMultipleLinksRule', () { + const rule = AutoFormatMultipleLinksRule(); + + final validLinks = [ + 'http://google.com', + 'https://www.google.com', + 'http://beginner.example.edu/#act', + 'http://beginner.example.edu#act', + 'https://birth.example.net/beds/ants.php#bait', + 'http://example.com/babies', + 'https://www.example.com/', + 'https://attack.example.edu/?acoustics=blade&bed=bed', + 'https://attack.example.edu?acoustics=blade&bed=bed', + 'http://basketball.example.com/', + 'https://birthday.example.com/birthday', + 'http://www.example.com/', + 'https://example.com/addition/action', + 'http://example.com/', + 'https://bite.example.net/#adjustment', + 'https://bite.example.net#adjustment', + 'http://www.example.net/badge.php?bedroom=anger', + 'https://brass.example.com/?anger=branch&actor=amusement#adjustment', + 'https://brass.example.com?anger=branch&actor=amusement#adjustment', + 'http://www.example.com/?action=birds&brass=apparatus', + 'http://www.example.com?action=birds&brass=apparatus', + 'https://example.net/', + ]; + + test('Insert link in text', () { + final delta = Delta()..insert('\n'); + final document = Document.fromDelta(delta); + + for (final link in validLinks) { + expect( + rule.apply(document, 0, data: link, len: 0), + Delta()..insert(link, {'link': link}), + ); + } + }); + }); } From c6fb24707270e0798af357cb4cd068016bc36f05 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 23 Oct 2024 19:17:43 +0300 Subject: [PATCH 086/113] fix(macos): Implement actions for ExpandSelectionToDocumentBoundaryIntent and ExpandSelectionToLineBreakIntent to use keyboard shortcuts, unrelated cleanup to the bug fix. (#2279) --- .../default_single_activator_intents.dart | 179 +++++++++++++++ .../editor_keyboard_shortcut_actions.dart} | 111 ++++++++- ...tor_keyboard_shortcut_actions_manager.dart | 204 +++++++++++++++++ .../editor_keyboard_shortcuts.dart} | 47 ++-- .../editor/raw_editor/raw_editor_state.dart | 212 +++--------------- .../default_single_activator_actions.dart | 206 ----------------- 6 files changed, 537 insertions(+), 422 deletions(-) create mode 100644 lib/src/editor/raw_editor/keyboard_shortcuts/default_single_activator_intents.dart rename lib/src/editor/raw_editor/{raw_editor_actions.dart => keyboard_shortcuts/editor_keyboard_shortcut_actions.dart} (87%) create mode 100644 lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions_manager.dart rename lib/src/editor/{widgets/keyboard_service_widget.dart => raw_editor/keyboard_shortcuts/editor_keyboard_shortcuts.dart} (86%) delete mode 100644 lib/src/editor/widgets/default_single_activator_actions.dart diff --git a/lib/src/editor/raw_editor/keyboard_shortcuts/default_single_activator_intents.dart b/lib/src/editor/raw_editor/keyboard_shortcuts/default_single_activator_intents.dart new file mode 100644 index 000000000..3d0aeb49c --- /dev/null +++ b/lib/src/editor/raw_editor/keyboard_shortcuts/default_single_activator_intents.dart @@ -0,0 +1,179 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart'; + +import '../../../common/utils/platform.dart'; +import '../../../document/attribute.dart'; +import 'editor_keyboard_shortcut_actions.dart'; + +final _isDesktopMacOS = isMacOS; + +@internal +Map defaultSinlgeActivatorIntents() { + return { + const SingleActivator( + LogicalKeyboardKey.escape, + ): const HideSelectionToolbarIntent(), + SingleActivator( + LogicalKeyboardKey.keyZ, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const UndoTextIntent(SelectionChangedCause.keyboard), + SingleActivator( + LogicalKeyboardKey.keyY, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const RedoTextIntent(SelectionChangedCause.keyboard), + + // Selection formatting. + SingleActivator( + LogicalKeyboardKey.keyB, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const ToggleTextStyleIntent(Attribute.bold), + SingleActivator( + LogicalKeyboardKey.keyU, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const ToggleTextStyleIntent(Attribute.underline), + SingleActivator( + LogicalKeyboardKey.keyI, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const ToggleTextStyleIntent(Attribute.italic), + SingleActivator( + LogicalKeyboardKey.keyS, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + shift: true, + ): const ToggleTextStyleIntent(Attribute.strikeThrough), + SingleActivator( + LogicalKeyboardKey.backquote, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const ToggleTextStyleIntent(Attribute.inlineCode), + SingleActivator( + LogicalKeyboardKey.tilde, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + shift: true, + ): const ToggleTextStyleIntent(Attribute.codeBlock), + SingleActivator( + LogicalKeyboardKey.keyB, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + shift: true, + ): const ToggleTextStyleIntent(Attribute.blockQuote), + SingleActivator( + LogicalKeyboardKey.keyK, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const QuillEditorApplyLinkIntent(), + + // Lists + SingleActivator( + LogicalKeyboardKey.keyL, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + shift: true, + ): const ToggleTextStyleIntent(Attribute.ul), + SingleActivator( + LogicalKeyboardKey.keyO, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + shift: true, + ): const ToggleTextStyleIntent(Attribute.ol), + SingleActivator( + LogicalKeyboardKey.keyC, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + shift: true, + ): const QuillEditorApplyCheckListIntent(), + + // Indents + SingleActivator( + LogicalKeyboardKey.keyM, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const IndentSelectionIntent(true), + SingleActivator( + LogicalKeyboardKey.keyM, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + shift: true, + ): const IndentSelectionIntent(false), + + // Headers + SingleActivator( + LogicalKeyboardKey.digit1, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const QuillEditorApplyHeaderIntent(Attribute.h1), + SingleActivator( + LogicalKeyboardKey.digit2, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const QuillEditorApplyHeaderIntent(Attribute.h2), + SingleActivator( + LogicalKeyboardKey.digit3, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const QuillEditorApplyHeaderIntent(Attribute.h3), + SingleActivator( + LogicalKeyboardKey.digit4, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const QuillEditorApplyHeaderIntent(Attribute.h4), + SingleActivator( + LogicalKeyboardKey.digit5, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const QuillEditorApplyHeaderIntent(Attribute.h5), + SingleActivator( + LogicalKeyboardKey.digit6, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const QuillEditorApplyHeaderIntent(Attribute.h6), + SingleActivator( + LogicalKeyboardKey.digit0, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const QuillEditorApplyHeaderIntent(Attribute.header), + + SingleActivator( + LogicalKeyboardKey.keyG, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const QuillEditorInsertEmbedIntent(Attribute.image), + + SingleActivator( + LogicalKeyboardKey.keyF, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const OpenSearchIntent(), + + // Arrow key scrolling + SingleActivator( + LogicalKeyboardKey.arrowUp, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const ScrollIntent(direction: AxisDirection.up), + SingleActivator( + LogicalKeyboardKey.arrowDown, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const ScrollIntent(direction: AxisDirection.down), + SingleActivator( + LogicalKeyboardKey.pageUp, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const ScrollIntent( + direction: AxisDirection.up, type: ScrollIncrementType.page), + SingleActivator( + LogicalKeyboardKey.pageDown, + control: !_isDesktopMacOS, + meta: _isDesktopMacOS, + ): const ScrollIntent( + direction: AxisDirection.down, type: ScrollIncrementType.page), + }; +} diff --git a/lib/src/editor/raw_editor/raw_editor_actions.dart b/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions.dart similarity index 87% rename from lib/src/editor/raw_editor/raw_editor_actions.dart rename to lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions.dart index e9cec3af6..b87f42484 100644 --- a/lib/src/editor/raw_editor/raw_editor_actions.dart +++ b/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; -import '../../../translations.dart'; -import '../../document/attribute.dart'; -import '../../document/style.dart'; -import '../../toolbar/buttons/link_style2_button.dart'; -import '../../toolbar/buttons/search/search_dialog.dart'; -import '../editor.dart'; -import '../widgets/link.dart'; -import 'raw_editor_state.dart'; -import 'raw_editor_text_boundaries.dart'; +import '../../../../translations.dart'; +import '../../../document/attribute.dart'; +import '../../../document/style.dart'; +import '../../../toolbar/buttons/link_style2_button.dart'; +import '../../../toolbar/buttons/search/search_dialog.dart'; +import '../../editor.dart'; +import '../../widgets/link.dart'; +import '../raw_editor_state.dart'; +import '../raw_editor_text_boundaries.dart'; // ------------------------------- Text Actions ------------------------------- class QuillEditorDeleteTextAction @@ -268,6 +268,98 @@ class QuillEditorExtendSelectionOrCaretPositionAction extends ContextAction< state.textEditingValue.selection.isValid; } +/// Expands the selection to the start/end of the document. +/// +/// This matches macOS behavior and differs from [ExpandSelectionToLineBreakIntent]. +/// +/// See: [ExpandSelectionToDocumentBoundaryIntent]. +class ExpandSelectionToDocumentBoundaryAction + extends ContextAction { + ExpandSelectionToDocumentBoundaryAction(this.state); + + final QuillRawEditorState state; + + @override + Object? invoke(ExpandSelectionToDocumentBoundaryIntent intent, + [BuildContext? context]) { + final currentSelection = state.controller.selection; + final documentLength = state.controller.document.length; + + final newSelection = intent.forward + ? currentSelection.copyWith( + extentOffset: documentLength, + ) + : currentSelection.copyWith( + extentOffset: 0, + ); + return Actions.invoke( + context ?? (throw StateError('BuildContext should not be null.')), + UpdateSelectionIntent( + state.textEditingValue, + newSelection, + SelectionChangedCause.keyboard, + ), + ); + } +} + +/// Extends the selection to the next/previous line break (`\n`). +/// +/// This behavior is standard on macOS. +/// +/// See: [ExpandSelectionToLineBreakIntent] +class ExpandSelectionToLineBreakAction + extends ContextAction { + ExpandSelectionToLineBreakAction(this.state); + + final QuillRawEditorState state; + @override + Object? invoke(ExpandSelectionToLineBreakIntent intent, + [BuildContext? context]) { + // Plain text of the document (needed to find line breaks) + final text = state.controller.plainTextEditingValue.text; + + final currentSelection = state.controller.selection; + + // Calculate the next or previous line break based on direction + final searchStartOffset = currentSelection.extentOffset; + + final targetLineBreak = () { + if (intent.forward) { + final nextLineBreak = text.indexOf('\n', searchStartOffset); + final noNextLineBreak = nextLineBreak == -1; + return noNextLineBreak ? text.length : nextLineBreak + 1; + } + + // Backward + + // Ensure (searchStartOffset - 1) is not negative to avoid [RangeError] + final safePreviousSearchOffset = + (searchStartOffset > 0) ? (searchStartOffset - 1) : 0; + + final previousLineBreak = + text.lastIndexOf('\n', safePreviousSearchOffset); + + final noPreviousLineBreak = previousLineBreak == -1; + return noPreviousLineBreak ? 0 : previousLineBreak; + }(); + + // Create a new selection, extending it to the line break was found + final newSelection = currentSelection.copyWith( + extentOffset: targetLineBreak, + ); + + return Actions.invoke( + context ?? (throw StateError('BuildContext should not be null.')), + UpdateSelectionIntent( + state.textEditingValue, + newSelection, + SelectionChangedCause.keyboard, + ), + ); + } +} + class QuillEditorUpdateTextSelectionToAdjacentLineAction< T extends DirectionalCaretMovementIntent> extends ContextAction { QuillEditorUpdateTextSelectionToAdjacentLineAction(this.state); @@ -627,6 +719,7 @@ class QuillEditorInsertEmbedIntent extends Intent { final Attribute type; } +/// Navigate to the start or end of the document class NavigateToDocumentBoundaryAction extends ContextAction { NavigateToDocumentBoundaryAction(this.state); diff --git a/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions_manager.dart b/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions_manager.dart new file mode 100644 index 000000000..bb03c2900 --- /dev/null +++ b/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions_manager.dart @@ -0,0 +1,204 @@ +import 'package:flutter/widgets.dart'; +import 'package:meta/meta.dart'; + +import '../raw_editor_state.dart'; +import '../raw_editor_text_boundaries.dart'; +import 'editor_keyboard_shortcut_actions.dart'; + +@internal +class EditorKeyboardShortcutsActionsManager { + EditorKeyboardShortcutsActionsManager({ + required this.rawEditorState, + required this.context, + }); + + final QuillRawEditorState rawEditorState; + final BuildContext context; + + void _updateSelection(UpdateSelectionIntent intent) { + rawEditorState.userUpdateTextEditingValue( + intent.currentTextEditingValue.copyWith(selection: intent.newSelection), + intent.cause, + ); + } + + QuillEditorTextBoundary _characterBoundary( + DirectionalTextEditingIntent intent) { + final atomicTextBoundary = + QuillEditorCharacterBoundary(rawEditorState.textEditingValue); + return QuillEditorCollapsedSelectionBoundary( + atomicTextBoundary, intent.forward); + } + + QuillEditorTextBoundary _nextWordBoundary( + DirectionalTextEditingIntent intent) { + final QuillEditorTextBoundary atomicTextBoundary; + final QuillEditorTextBoundary boundary; + + // final TextEditingValue textEditingValue = + // _textEditingValueForTextLayoutMetrics; + atomicTextBoundary = + QuillEditorCharacterBoundary(rawEditorState.textEditingValue); + // This isn't enough. Newline characters. + boundary = QuillEditorExpandedTextBoundary( + QuillEditorWhitespaceBoundary(rawEditorState.textEditingValue), + QuillEditorWordBoundary( + rawEditorState.renderEditor, rawEditorState.textEditingValue)); + + final mixedBoundary = intent.forward + ? QuillEditorMixedBoundary(atomicTextBoundary, boundary) + : QuillEditorMixedBoundary(boundary, atomicTextBoundary); + // Use a _MixedBoundary to make sure we don't leave invalid codepoints in + // the field after deletion. + return QuillEditorCollapsedSelectionBoundary(mixedBoundary, intent.forward); + } + + QuillEditorTextBoundary _linebreak(DirectionalTextEditingIntent intent) { + final QuillEditorTextBoundary atomicTextBoundary; + final QuillEditorTextBoundary boundary; + + // final TextEditingValue textEditingValue = + // _textEditingValueforTextLayoutMetrics; + atomicTextBoundary = + QuillEditorCharacterBoundary(rawEditorState.textEditingValue); + boundary = QuillEditorLineBreak( + rawEditorState.renderEditor, rawEditorState.textEditingValue); + + // The _MixedBoundary is to make sure we don't leave invalid code units in + // the field after deletion. + // `boundary` doesn't need to be wrapped in a _CollapsedSelectionBoundary, + // since the document boundary is unique and the linebreak boundary is + // already caret-location based. + return intent.forward + ? QuillEditorMixedBoundary( + QuillEditorCollapsedSelectionBoundary(atomicTextBoundary, true), + boundary) + : QuillEditorMixedBoundary( + boundary, + QuillEditorCollapsedSelectionBoundary(atomicTextBoundary, false), + ); + } + + void _replaceText(ReplaceTextIntent intent) { + rawEditorState.userUpdateTextEditingValue( + intent.currentTextEditingValue + .replaced(intent.replacementRange, intent.replacementText), + intent.cause, + ); + } + + late final Action _replaceTextAction = + CallbackAction(onInvoke: _replaceText); + + QuillEditorTextBoundary _documentBoundary( + DirectionalTextEditingIntent intent) => + QuillEditorDocumentBoundary(rawEditorState.textEditingValue); + + Action _makeOverridable(Action defaultAction) { + return Action.overridable( + context: context, defaultAction: defaultAction); + } + + late final Action _updateSelectionAction = + CallbackAction(onInvoke: _updateSelection); + + late final QuillEditorUpdateTextSelectionToAdjacentLineAction< + ExtendSelectionVerticallyToAdjacentLineIntent> adjacentLineAction = + QuillEditorUpdateTextSelectionToAdjacentLineAction< + ExtendSelectionVerticallyToAdjacentLineIntent>(rawEditorState); + + late final _adjacentPageAction = + QuillEditorUpdateTextSelectionToAdjacentPageAction< + ExtendSelectionVerticallyToAdjacentPageIntent>(rawEditorState); + + late final QuillEditorToggleTextStyleAction _formatSelectionAction = + QuillEditorToggleTextStyleAction(rawEditorState); + + late final QuillEditorIndentSelectionAction _indentSelectionAction = + QuillEditorIndentSelectionAction(rawEditorState); + + late final QuillEditorOpenSearchAction _openSearchAction = + QuillEditorOpenSearchAction(rawEditorState); + late final QuillEditorApplyHeaderAction _applyHeaderAction = + QuillEditorApplyHeaderAction(rawEditorState); + late final QuillEditorApplyCheckListAction _applyCheckListAction = + QuillEditorApplyCheckListAction(rawEditorState); + + late final Map> _actions = >{ + DoNothingAndStopPropagationTextIntent: DoNothingAction(consumesKey: false), + ReplaceTextIntent: _replaceTextAction, + UpdateSelectionIntent: _updateSelectionAction, + DirectionalFocusIntent: DirectionalFocusAction.forTextField(), + + // Delete + DeleteCharacterIntent: _makeOverridable( + QuillEditorDeleteTextAction( + rawEditorState, _characterBoundary)), + DeleteToNextWordBoundaryIntent: _makeOverridable( + QuillEditorDeleteTextAction( + rawEditorState, _nextWordBoundary)), + DeleteToLineBreakIntent: _makeOverridable( + QuillEditorDeleteTextAction( + rawEditorState, _linebreak)), + + // Extend/Move Selection + ExtendSelectionByCharacterIntent: _makeOverridable( + QuillEditorUpdateTextSelectionAction( + rawEditorState, + false, + _characterBoundary, + )), + ExtendSelectionToNextWordBoundaryIntent: _makeOverridable( + QuillEditorUpdateTextSelectionAction< + ExtendSelectionToNextWordBoundaryIntent>( + rawEditorState, true, _nextWordBoundary)), + ExtendSelectionToLineBreakIntent: _makeOverridable( + QuillEditorUpdateTextSelectionAction( + rawEditorState, true, _linebreak)), + ExtendSelectionVerticallyToAdjacentLineIntent: + _makeOverridable(adjacentLineAction), + ExtendSelectionToDocumentBoundaryIntent: _makeOverridable( + QuillEditorUpdateTextSelectionAction< + ExtendSelectionToDocumentBoundaryIntent>( + rawEditorState, true, _documentBoundary)), + ExtendSelectionToNextWordBoundaryOrCaretLocationIntent: _makeOverridable( + QuillEditorExtendSelectionOrCaretPositionAction( + rawEditorState, _nextWordBoundary)), + ExpandSelectionToDocumentBoundaryIntent: _makeOverridable( + ExpandSelectionToDocumentBoundaryAction(rawEditorState)), + ExpandSelectionToLineBreakIntent: + _makeOverridable(ExpandSelectionToLineBreakAction(rawEditorState)), + + // Copy Paste + SelectAllTextIntent: + _makeOverridable(QuillEditorSelectAllAction(rawEditorState)), + CopySelectionTextIntent: + _makeOverridable(QuillEditorCopySelectionAction(rawEditorState)), + PasteTextIntent: _makeOverridable(CallbackAction( + onInvoke: (intent) => rawEditorState.pasteText(intent.cause))), + + HideSelectionToolbarIntent: + _makeOverridable(QuillEditorHideSelectionToolbarAction(rawEditorState)), + UndoTextIntent: + _makeOverridable(QuillEditorUndoKeyboardAction(rawEditorState)), + RedoTextIntent: + _makeOverridable(QuillEditorRedoKeyboardAction(rawEditorState)), + + OpenSearchIntent: _openSearchAction, + + // Selection Formatting + ToggleTextStyleIntent: _formatSelectionAction, + IndentSelectionIntent: _indentSelectionAction, + QuillEditorApplyHeaderIntent: _applyHeaderAction, + QuillEditorApplyCheckListIntent: _applyCheckListAction, + QuillEditorApplyLinkIntent: QuillEditorApplyLinkAction(rawEditorState), + ScrollToDocumentBoundaryIntent: + NavigateToDocumentBoundaryAction(rawEditorState), + + // Paging and scrolling + ExtendSelectionVerticallyToAdjacentPageIntent: _adjacentPageAction, + ScrollIntent: QuillEditorScrollAction(rawEditorState), + }; + + Map> get actions => _actions; +} diff --git a/lib/src/editor/widgets/keyboard_service_widget.dart b/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcuts.dart similarity index 86% rename from lib/src/editor/widgets/keyboard_service_widget.dart rename to lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcuts.dart index 1231fe830..336726628 100644 --- a/lib/src/editor/widgets/keyboard_service_widget.dart +++ b/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcuts.dart @@ -1,22 +1,23 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; - -import '../../common/utils/cast.dart'; -import '../../common/utils/platform.dart'; -import '../../controller/quill_controller.dart'; -import '../../document/attribute.dart'; -import '../../document/document.dart'; -import '../../document/nodes/block.dart'; -import '../../document/nodes/leaf.dart' as leaf; -import '../../document/nodes/line.dart'; -import '../raw_editor/config/events/character_shortcuts_events.dart'; -import '../raw_editor/config/events/space_shortcut_events.dart'; -import 'default_single_activator_actions.dart'; -import 'keyboard_listener.dart'; - -class QuillKeyboardServiceWidget extends StatelessWidget { - const QuillKeyboardServiceWidget({ +import 'package:meta/meta.dart'; + +import '../../../common/utils/cast.dart'; +import '../../../controller/quill_controller.dart'; +import '../../../document/attribute.dart'; +import '../../../document/document.dart'; +import '../../../document/nodes/block.dart'; +import '../../../document/nodes/leaf.dart' as leaf; +import '../../../document/nodes/line.dart'; +import '../../widgets/keyboard_listener.dart'; +import '../config/events/character_shortcuts_events.dart'; +import '../config/events/space_shortcut_events.dart'; +import 'default_single_activator_intents.dart'; + +@internal +class EditorKeyboardShortcuts extends StatelessWidget { + const EditorKeyboardShortcuts({ required this.actions, required this.constraints, required this.focusNode, @@ -45,17 +46,19 @@ class QuillKeyboardServiceWidget extends StatelessWidget { @override Widget build(BuildContext context) { - final isDesktopMacOS = isMacOS; return Shortcuts( /// Merge with widget.configurations.customShortcuts /// first to allow user's defined shortcuts to take /// priority when activation triggers are the same - shortcuts: mergeMaps({...?customShortcuts}, - {...defaultSinlgeActivatorActions(isDesktopMacOS)}), + shortcuts: mergeMaps( + {...?customShortcuts}, + {...defaultSinlgeActivatorIntents()}, + ), child: Actions( - actions: mergeMaps>(actions, { - ...?customActions, - }), + actions: mergeMaps>( + actions, + {...?customActions}, + ), child: Focus( focusNode: focusNode, onKeyEvent: _onKeyEvent, diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index b7e3d57e0..2f1e3d050 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -29,18 +29,17 @@ import '../../editor_toolbar_controller_shared/clipboard/clipboard_service_provi import '../editor.dart'; import '../widgets/cursor.dart'; import '../widgets/default_styles.dart'; -import '../widgets/keyboard_service_widget.dart'; import '../widgets/link.dart'; import '../widgets/proxy.dart'; import '../widgets/text/text_block.dart'; import '../widgets/text/text_line.dart'; import '../widgets/text/text_selection.dart'; +import 'keyboard_shortcuts/editor_keyboard_shortcut_actions_manager.dart'; +import 'keyboard_shortcuts/editor_keyboard_shortcuts.dart'; import 'raw_editor.dart'; -import 'raw_editor_actions.dart'; import 'raw_editor_render_object.dart'; import 'raw_editor_state_selection_delegate_mixin.dart'; import 'raw_editor_state_text_input_client_mixin.dart'; -import 'raw_editor_text_boundaries.dart'; import 'scribble_focusable.dart'; class QuillRawEditorState extends EditorState @@ -50,6 +49,8 @@ class QuillRawEditorState extends EditorState TickerProviderStateMixin, RawEditorStateTextInputClientMixin, RawEditorStateSelectionDelegateMixin { + late final EditorKeyboardShortcutsActionsManager _shortcutActionsManager; + final GlobalKey _editorKey = GlobalKey(); KeyboardVisibilityController? _keyboardVisibilityController; @@ -530,8 +531,8 @@ class QuillRawEditorState extends EditorState }, child: QuillStyles( data: _styles!, - child: QuillKeyboardServiceWidget( - actions: _actions, + child: EditorKeyboardShortcuts( + actions: _shortcutActionsManager.actions, characterEvents: widget.configurations.characterShortcutEvents, spaceEvents: widget.configurations.spaceShortcutEvents, constraints: constraints, @@ -839,6 +840,11 @@ class QuillRawEditorState extends EditorState @override void initState() { super.initState(); + _shortcutActionsManager = EditorKeyboardShortcutsActionsManager( + rawEditorState: this, + context: context, + ); + if (_clipboardStatus != null) { _clipboardStatus!.addListener(_onChangedClipboardStatus); } @@ -1053,7 +1059,8 @@ class QuillRawEditorState extends EditorState } } - _adjacentLineAction.stopCurrentVerticalRunIfSelectionChanges(); + _shortcutActionsManager.adjacentLineAction + .stopCurrentVerticalRunIfSelectionChanges(); } void _onChangeTextEditingValue([bool ignoreCaret = false]) { @@ -1284,14 +1291,6 @@ class QuillRawEditorState extends EditorState } } - void _replaceText(ReplaceTextIntent intent) { - userUpdateTextEditingValue( - intent.currentTextEditingValue - .replaced(intent.replacementRange, intent.replacementText), - intent.cause, - ); - } - @override bool get wantKeepAlive => widget.configurations.focusNode.hasFocus; @@ -1301,171 +1300,6 @@ class QuillRawEditorState extends EditorState late AnimationController _floatingCursorResetController; - // --------------------------- Text Editing Actions -------------------------- - - QuillEditorTextBoundary _characterBoundary( - DirectionalTextEditingIntent intent) { - final atomicTextBoundary = QuillEditorCharacterBoundary(textEditingValue); - return QuillEditorCollapsedSelectionBoundary( - atomicTextBoundary, intent.forward); - } - - QuillEditorTextBoundary _nextWordBoundary( - DirectionalTextEditingIntent intent) { - final QuillEditorTextBoundary atomicTextBoundary; - final QuillEditorTextBoundary boundary; - - // final TextEditingValue textEditingValue = - // _textEditingValueForTextLayoutMetrics; - atomicTextBoundary = QuillEditorCharacterBoundary(textEditingValue); - // This isn't enough. Newline characters. - boundary = QuillEditorExpandedTextBoundary( - QuillEditorWhitespaceBoundary(textEditingValue), - QuillEditorWordBoundary(renderEditor, textEditingValue)); - - final mixedBoundary = intent.forward - ? QuillEditorMixedBoundary(atomicTextBoundary, boundary) - : QuillEditorMixedBoundary(boundary, atomicTextBoundary); - // Use a _MixedBoundary to make sure we don't leave invalid codepoints in - // the field after deletion. - return QuillEditorCollapsedSelectionBoundary(mixedBoundary, intent.forward); - } - - QuillEditorTextBoundary _linebreak(DirectionalTextEditingIntent intent) { - final QuillEditorTextBoundary atomicTextBoundary; - final QuillEditorTextBoundary boundary; - - // final TextEditingValue textEditingValue = - // _textEditingValueforTextLayoutMetrics; - atomicTextBoundary = QuillEditorCharacterBoundary(textEditingValue); - boundary = QuillEditorLineBreak(renderEditor, textEditingValue); - - // The _MixedBoundary is to make sure we don't leave invalid code units in - // the field after deletion. - // `boundary` doesn't need to be wrapped in a _CollapsedSelectionBoundary, - // since the document boundary is unique and the linebreak boundary is - // already caret-location based. - return intent.forward - ? QuillEditorMixedBoundary( - QuillEditorCollapsedSelectionBoundary(atomicTextBoundary, true), - boundary) - : QuillEditorMixedBoundary( - boundary, - QuillEditorCollapsedSelectionBoundary(atomicTextBoundary, false), - ); - } - - QuillEditorTextBoundary _documentBoundary( - DirectionalTextEditingIntent intent) => - QuillEditorDocumentBoundary(textEditingValue); - - Action _makeOverridable(Action defaultAction) { - return Action.overridable( - context: context, defaultAction: defaultAction); - } - - late final Action _replaceTextAction = - CallbackAction(onInvoke: _replaceText); - - void _updateSelection(UpdateSelectionIntent intent) { - userUpdateTextEditingValue( - intent.currentTextEditingValue.copyWith(selection: intent.newSelection), - intent.cause, - ); - } - - late final Action _updateSelectionAction = - CallbackAction(onInvoke: _updateSelection); - - late final QuillEditorUpdateTextSelectionToAdjacentLineAction< - ExtendSelectionVerticallyToAdjacentLineIntent> _adjacentLineAction = - QuillEditorUpdateTextSelectionToAdjacentLineAction< - ExtendSelectionVerticallyToAdjacentLineIntent>(this); - - late final _adjacentPageAction = - QuillEditorUpdateTextSelectionToAdjacentPageAction< - ExtendSelectionVerticallyToAdjacentPageIntent>(this); - - late final QuillEditorToggleTextStyleAction _formatSelectionAction = - QuillEditorToggleTextStyleAction(this); - - late final QuillEditorIndentSelectionAction _indentSelectionAction = - QuillEditorIndentSelectionAction(this); - - late final QuillEditorOpenSearchAction _openSearchAction = - QuillEditorOpenSearchAction(this); - late final QuillEditorApplyHeaderAction _applyHeaderAction = - QuillEditorApplyHeaderAction(this); - late final QuillEditorApplyCheckListAction _applyCheckListAction = - QuillEditorApplyCheckListAction(this); - - late final Map> _actions = >{ - DoNothingAndStopPropagationTextIntent: DoNothingAction(consumesKey: false), - ReplaceTextIntent: _replaceTextAction, - UpdateSelectionIntent: _updateSelectionAction, - DirectionalFocusIntent: DirectionalFocusAction.forTextField(), - - // Delete - DeleteCharacterIntent: _makeOverridable( - QuillEditorDeleteTextAction( - this, _characterBoundary)), - DeleteToNextWordBoundaryIntent: _makeOverridable( - QuillEditorDeleteTextAction( - this, _nextWordBoundary)), - DeleteToLineBreakIntent: _makeOverridable( - QuillEditorDeleteTextAction(this, _linebreak)), - - // Extend/Move Selection - ExtendSelectionByCharacterIntent: _makeOverridable( - QuillEditorUpdateTextSelectionAction( - this, - false, - _characterBoundary, - )), - ExtendSelectionToNextWordBoundaryIntent: _makeOverridable( - QuillEditorUpdateTextSelectionAction< - ExtendSelectionToNextWordBoundaryIntent>( - this, true, _nextWordBoundary)), - ExtendSelectionToLineBreakIntent: _makeOverridable( - QuillEditorUpdateTextSelectionAction( - this, true, _linebreak)), - ExtendSelectionVerticallyToAdjacentLineIntent: - _makeOverridable(_adjacentLineAction), - ExtendSelectionToDocumentBoundaryIntent: _makeOverridable( - QuillEditorUpdateTextSelectionAction< - ExtendSelectionToDocumentBoundaryIntent>( - this, true, _documentBoundary)), - ExtendSelectionToNextWordBoundaryOrCaretLocationIntent: _makeOverridable( - QuillEditorExtendSelectionOrCaretPositionAction( - this, _nextWordBoundary)), - - // Copy Paste - SelectAllTextIntent: _makeOverridable(QuillEditorSelectAllAction(this)), - CopySelectionTextIntent: - _makeOverridable(QuillEditorCopySelectionAction(this)), - PasteTextIntent: _makeOverridable(CallbackAction( - onInvoke: (intent) => pasteText(intent.cause))), - - HideSelectionToolbarIntent: - _makeOverridable(QuillEditorHideSelectionToolbarAction(this)), - UndoTextIntent: _makeOverridable(QuillEditorUndoKeyboardAction(this)), - RedoTextIntent: _makeOverridable(QuillEditorRedoKeyboardAction(this)), - - OpenSearchIntent: _openSearchAction, - - // Selection Formatting - ToggleTextStyleIntent: _formatSelectionAction, - IndentSelectionIntent: _indentSelectionAction, - QuillEditorApplyHeaderIntent: _applyHeaderAction, - QuillEditorApplyCheckListIntent: _applyCheckListAction, - QuillEditorApplyLinkIntent: QuillEditorApplyLinkAction(this), - ScrollToDocumentBoundaryIntent: NavigateToDocumentBoundaryAction(this), - - // Paging and scrolling - ExtendSelectionVerticallyToAdjacentPageIntent: _adjacentPageAction, - ScrollIntent: QuillEditorScrollAction(this), - }; - @override void insertTextPlaceholder(Size size) { // this is needed for Scribble (Stylus input) in Apple platforms @@ -1486,16 +1320,24 @@ class QuillRawEditorState extends EditorState // TODO: implement didChangeInputControl } + /// macOS-specific method that should not be called on other platforms. + /// This method interacts with the `NSStandardKeyBindingResponding` protocol + /// from Cocoa, which is available only on macOS systems. @override void performSelector(String selectorName) { + assert( + isMacOSApp, + 'Should call performSelector() only on macOS desktop platform.', + ); final intent = intentForMacOSSelector(selectorName); - - if (intent != null) { - final primaryContext = primaryFocus?.context; - if (primaryContext != null) { - Actions.invoke(primaryContext, intent); - } + if (intent == null) { + return; + } + final primaryContext = primaryFocus?.context; + if (primaryContext == null) { + return; } + Actions.invoke(primaryContext, intent); } @override diff --git a/lib/src/editor/widgets/default_single_activator_actions.dart b/lib/src/editor/widgets/default_single_activator_actions.dart deleted file mode 100644 index 4eb927100..000000000 --- a/lib/src/editor/widgets/default_single_activator_actions.dart +++ /dev/null @@ -1,206 +0,0 @@ -import 'package:flutter/material.dart' - show - AxisDirection, - Intent, - RedoTextIntent, - ScrollIncrementType, - ScrollIntent, - ScrollToDocumentBoundaryIntent, - SelectionChangedCause, - SingleActivator, - UndoTextIntent; -import 'package:flutter/services.dart' - show LogicalKeyboardKey, SelectionChangedCause; - -import '../../document/attribute.dart'; -import '../raw_editor/raw_editor_actions.dart' - show - HideSelectionToolbarIntent, - IndentSelectionIntent, - OpenSearchIntent, - QuillEditorApplyCheckListIntent, - QuillEditorApplyHeaderIntent, - QuillEditorApplyLinkIntent, - QuillEditorInsertEmbedIntent, - ToggleTextStyleIntent; - -Map defaultSinlgeActivatorActions( - bool isDesktopMacOS) => - { - const SingleActivator( - LogicalKeyboardKey.escape, - ): const HideSelectionToolbarIntent(), - SingleActivator( - LogicalKeyboardKey.keyZ, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const UndoTextIntent(SelectionChangedCause.keyboard), - SingleActivator( - LogicalKeyboardKey.keyY, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const RedoTextIntent(SelectionChangedCause.keyboard), - - // Selection formatting. - SingleActivator( - LogicalKeyboardKey.keyB, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const ToggleTextStyleIntent(Attribute.bold), - SingleActivator( - LogicalKeyboardKey.keyU, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const ToggleTextStyleIntent(Attribute.underline), - SingleActivator( - LogicalKeyboardKey.keyI, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const ToggleTextStyleIntent(Attribute.italic), - SingleActivator( - LogicalKeyboardKey.keyS, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - shift: true, - ): const ToggleTextStyleIntent(Attribute.strikeThrough), - SingleActivator( - LogicalKeyboardKey.backquote, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const ToggleTextStyleIntent(Attribute.inlineCode), - SingleActivator( - LogicalKeyboardKey.tilde, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - shift: true, - ): const ToggleTextStyleIntent(Attribute.codeBlock), - SingleActivator( - LogicalKeyboardKey.keyB, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - shift: true, - ): const ToggleTextStyleIntent(Attribute.blockQuote), - SingleActivator( - LogicalKeyboardKey.keyK, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const QuillEditorApplyLinkIntent(), - - // Lists - SingleActivator( - LogicalKeyboardKey.keyL, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - shift: true, - ): const ToggleTextStyleIntent(Attribute.ul), - SingleActivator( - LogicalKeyboardKey.keyO, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - shift: true, - ): const ToggleTextStyleIntent(Attribute.ol), - SingleActivator( - LogicalKeyboardKey.keyC, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - shift: true, - ): const QuillEditorApplyCheckListIntent(), - - // Indents - SingleActivator( - LogicalKeyboardKey.keyM, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const IndentSelectionIntent(true), - SingleActivator( - LogicalKeyboardKey.keyM, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - shift: true, - ): const IndentSelectionIntent(false), - - // Headers - SingleActivator( - LogicalKeyboardKey.digit1, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const QuillEditorApplyHeaderIntent(Attribute.h1), - SingleActivator( - LogicalKeyboardKey.digit2, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const QuillEditorApplyHeaderIntent(Attribute.h2), - SingleActivator( - LogicalKeyboardKey.digit3, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const QuillEditorApplyHeaderIntent(Attribute.h3), - SingleActivator( - LogicalKeyboardKey.digit4, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const QuillEditorApplyHeaderIntent(Attribute.h4), - SingleActivator( - LogicalKeyboardKey.digit5, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const QuillEditorApplyHeaderIntent(Attribute.h5), - SingleActivator( - LogicalKeyboardKey.digit6, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const QuillEditorApplyHeaderIntent(Attribute.h6), - SingleActivator( - LogicalKeyboardKey.digit0, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const QuillEditorApplyHeaderIntent(Attribute.header), - - SingleActivator( - LogicalKeyboardKey.keyG, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const QuillEditorInsertEmbedIntent(Attribute.image), - - SingleActivator( - LogicalKeyboardKey.keyF, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const OpenSearchIntent(), - - // Navigate to the start or end of the document - SingleActivator( - LogicalKeyboardKey.home, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const ScrollToDocumentBoundaryIntent(forward: false), - SingleActivator( - LogicalKeyboardKey.end, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const ScrollToDocumentBoundaryIntent(forward: true), - - // Arrow key scrolling - SingleActivator( - LogicalKeyboardKey.arrowUp, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const ScrollIntent(direction: AxisDirection.up), - SingleActivator( - LogicalKeyboardKey.arrowDown, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const ScrollIntent(direction: AxisDirection.down), - SingleActivator( - LogicalKeyboardKey.pageUp, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const ScrollIntent( - direction: AxisDirection.up, type: ScrollIncrementType.page), - SingleActivator( - LogicalKeyboardKey.pageDown, - control: !isDesktopMacOS, - meta: isDesktopMacOS, - ): const ScrollIntent( - direction: AxisDirection.down, type: ScrollIncrementType.page), - }; From bbf1ccf76cca002fffaa7bbbcda6c2d5a583a620 Mon Sep 17 00:00:00 2001 From: EchoEllet Date: Wed, 23 Oct 2024 17:01:21 +0000 Subject: [PATCH 087/113] chore(version): update to version 10.8.5 --- CHANGELOG.md | 10 ++++++++++ CHANGELOG_DATA.json | 1 + flutter_quill_extensions/CHANGELOG.md | 10 ++++++++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/CHANGELOG.md | 10 ++++++++++ flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 7 files changed, 34 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76a9cb1d5..45a3e484d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. +## 10.8.5 + +* fix: allow all correct URLs to be formatted by @orevial in https://github.com/singerdmx/flutter-quill/pull/2328 +* fix(macos): Implement actions for ExpandSelectionToDocumentBoundaryIntent and ExpandSelectionToLineBreakIntent to use keyboard shortcuts, unrelated cleanup to the bug fix. by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2279 + +## New Contributors +* @orevial made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2328 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.4...v10.8.5 + ## 10.8.4 - [Fixes an unhandled exception](https://github.com/singerdmx/flutter-quill/commit/8dd559b825030d29b30b32b353a08dcc13dc42b7) in case `getClipboardFiles()` wasn't supported diff --git a/CHANGELOG_DATA.json b/CHANGELOG_DATA.json index 703289855..2ebc06c7e 100644 --- a/CHANGELOG_DATA.json +++ b/CHANGELOG_DATA.json @@ -1,4 +1,5 @@ { + "10.8.5": "* fix: allow all correct URLs to be formatted by @orevial in https://github.com/singerdmx/flutter-quill/pull/2328\r\n* fix(macos): Implement actions for ExpandSelectionToDocumentBoundaryIntent and ExpandSelectionToLineBreakIntent to use keyboard shortcuts, unrelated cleanup to the bug fix. by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2279\r\n\r\n## New Contributors\r\n* @orevial made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2328\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.4...v10.8.5", "10.8.4": "- [Fixes an unhandled exception](https://github.com/singerdmx/flutter-quill/commit/8dd559b825030d29b30b32b353a08dcc13dc42b7) in case `getClipboardFiles()` wasn't supported\r\n- [Updates min version](https://github.com/singerdmx/flutter-quill/commit/49569e47b038c5f61b7521571c102cf5ad5a0e3f) of internal dependency `quill_native_bridge`\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.3...v10.8.4", "10.8.3": "This release is identical to [v10.8.3-dev.0](https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.3-dev.0), mainly published to bump the minimum version of [flutter_quill](https://pub.dev/packages/flutter_quill) in [flutter_quill_extensions](https://pub.dev/packages/flutter_quill_extensions) and to publish [quill-super-clipboard](https://github.com/FlutterQuill/quill-super-clipboard/).\r\n\r\nA new identical release `10.9.0` will be published soon with a release description.\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3", "10.8.3-dev.0": "A non-pre-release version with this change will be published soon.\r\n\r\n* feat: Use quill_native_bridge as default impl in DefaultClipboardService, fix related bugs in the extensions package by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2230\r\n\r\n\r\n**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.2...v10.8.3-dev.0", diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 76a9cb1d5..45a3e484d 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. +## 10.8.5 + +* fix: allow all correct URLs to be formatted by @orevial in https://github.com/singerdmx/flutter-quill/pull/2328 +* fix(macos): Implement actions for ExpandSelectionToDocumentBoundaryIntent and ExpandSelectionToLineBreakIntent to use keyboard shortcuts, unrelated cleanup to the bug fix. by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2279 + +## New Contributors +* @orevial made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2328 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.4...v10.8.5 + ## 10.8.4 - [Fixes an unhandled exception](https://github.com/singerdmx/flutter-quill/commit/8dd559b825030d29b30b32b353a08dcc13dc42b7) in case `getClipboardFiles()` wasn't supported diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 55a2fc59e..466e554d8 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 10.8.4 +version: 10.8.5 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/CHANGELOG.md b/flutter_quill_test/CHANGELOG.md index 76a9cb1d5..45a3e484d 100644 --- a/flutter_quill_test/CHANGELOG.md +++ b/flutter_quill_test/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. +## 10.8.5 + +* fix: allow all correct URLs to be formatted by @orevial in https://github.com/singerdmx/flutter-quill/pull/2328 +* fix(macos): Implement actions for ExpandSelectionToDocumentBoundaryIntent and ExpandSelectionToLineBreakIntent to use keyboard shortcuts, unrelated cleanup to the bug fix. by @EchoEllet in https://github.com/singerdmx/flutter-quill/pull/2279 + +## New Contributors +* @orevial made their first contribution at https://github.com/singerdmx/flutter-quill/pull/2328 + +**Full Changelog**: https://github.com/singerdmx/flutter-quill/compare/v10.8.4...v10.8.5 + ## 10.8.4 - [Fixes an unhandled exception](https://github.com/singerdmx/flutter-quill/commit/8dd559b825030d29b30b32b353a08dcc13dc42b7) in case `getClipboardFiles()` wasn't supported diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 9e676c4fb..ad9b1d833 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 10.8.4 +version: 10.8.5 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 19829c413..7c035f3fb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: "A rich text editor built for Android, iOS, Web, and desktop platforms. It's the WYSIWYG editor and a Quill component for Flutter." -version: 10.8.4 +version: 10.8.5 homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 1cc1b50ec67b55b8a146b0e9a141ea36ed57c4a0 Mon Sep 17 00:00:00 2001 From: Doug Todd <53582591+Zambrella@users.noreply.github.com> Date: Thu, 24 Oct 2024 12:01:25 +0100 Subject: [PATCH 088/113] fix: link menu action Cupertino modal popup now does NOT use root nav (#2332) * fix: link menu action cupertino modal popup now does not use root navigator This is to fix a bug where when using nested navigators the modal popup wouldn't pop. This also brings the behavior into parity with the Android/Material equivalent. * chore: add comment referencing bug fix #1170 --------- Co-authored-by: Doug Todd Co-authored-by: Ellet --- lib/src/editor/widgets/link.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/editor/widgets/link.dart b/lib/src/editor/widgets/link.dart index f6b9f755c..7f2a69af3 100644 --- a/lib/src/editor/widgets/link.dart +++ b/lib/src/editor/widgets/link.dart @@ -150,6 +150,8 @@ class QuillTextLink { Future _showCupertinoLinkMenu( BuildContext context, String link) async { final result = await showCupertinoModalPopup( + // Set useRootNavigator to false to fix https://github.com/singerdmx/flutter-quill/issues/1170 + useRootNavigator: false, context: context, builder: (ctx) { return CupertinoActionSheet( From 0bd75134e476fb9a1a2bd4491ad1e7596470d558 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Tue, 17 Sep 2024 18:13:49 -0400 Subject: [PATCH 089/113] Partial improvements --- lib/src/editor/editor.dart | 4 ++++ lib/src/editor/raw_editor/raw_editor_state.dart | 1 + lib/src/editor/widgets/text/text_line.dart | 3 +++ 3 files changed, 8 insertions(+) diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index f9e4a0605..0eceeacfc 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -33,6 +33,7 @@ import 'widgets/box.dart'; import 'widgets/cursor.dart'; import 'widgets/delegate.dart'; import 'widgets/float_cursor.dart'; +import 'widgets/text/text_line.dart'; import 'widgets/text/text_selection.dart'; /// Base interface for editable render objects. @@ -1097,6 +1098,9 @@ class RenderEditor extends RenderEditableContainerBox }) { final fromPosition = getPositionForOffset(from); final toPosition = to == null ? null : getPositionForOffset(to); + final child = childAtPosition(toPosition ?? fromPosition); + print(child as RenderEditableTextLine); + print(child.line); var baseOffset = fromPosition.offset; var extentOffset = fromPosition.offset; diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 2f1e3d050..032cf3906 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -25,6 +25,7 @@ import '../../document/nodes/block.dart'; import '../../document/nodes/embeddable.dart'; import '../../document/nodes/line.dart'; import '../../document/nodes/node.dart'; +import '../../document/style.dart'; import '../../editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; import '../editor.dart'; import '../widgets/cursor.dart'; diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 69cea2e88..766b6ccd7 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -296,6 +296,9 @@ class _TextLineState extends State { } if (nodes.isEmpty && kIsWeb && addWebNodeIfNeeded) { nodes = LinkedList()..add(leaf.QuillText('\u{200B}')); + } else if(nodes.isEmpty && widget.line.style.containsKey('header')){ + lineStyle = lineStyle.copyWith(color: defaultStyles.placeHolder?.style.color); + nodes = LinkedList()..add(leaf.QuillText('Header Placeholder')); } final isComposingRangeOutOfLine = !widget.composingRange.isValid || From 4b36413a4a783e4951555fee49d2c16ada040ea5 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Wed, 18 Sep 2024 12:29:35 -0400 Subject: [PATCH 090/113] Fix(merge): missing trailing comma on EditableTextLine constructor --- lib/src/editor/widgets/text/text_line.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 766b6ccd7..1b7238fdc 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -770,7 +770,10 @@ class EditableTextLine extends RenderObjectWidget { color, cursorCont, inlineCodeStyle, - cursorParagrahPlaceholderConfiguration); + composingRange, + composingColor, + cursorParagrahPlaceholderConfiguration, + ); } @override From 364cb19cb4356ee0e53d6b62f19d7d1d30b25481 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Mon, 28 Oct 2024 13:51:51 -0400 Subject: [PATCH 091/113] Chore: textDirection in build method from PlaceholderBuilder was changed to be optional --- .../placeholder/placeholder_builder_internal.dart | 8 +------- lib/src/editor/widgets/text/text_line.dart | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index abf2d81d5..2b5166e7d 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -1,17 +1,11 @@ // This file is only for internal use import 'package:flutter/material.dart' show - Align, - Alignment, - CrossAxisAlignment, Expanded, - MainAxisAlignment, - PlaceholderAlignment, Row, StrutStyle, Text, TextAlign, - TextBaseline, TextDirection, TextStyle, TextWidthBasis, @@ -84,7 +78,7 @@ class PlaceholderBuilder { WidgetSpan? build({ required Attribute blockAttribute, required TextStyle lineStyle, - required TextDirection textDirection, + TextDirection? textDirection, required TextAlign align, StrutStyle? strutStyle, }) { diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 1b7238fdc..6847949ea 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -281,7 +281,7 @@ class _TextLineState extends State { final placeholderWidget = widget.placeholderBuilder!.build( blockAttribute: widget.line.style.attributes[attrKey]!, lineStyle: style, - textDirection: widget.textDirection ?? Directionality.of(context), + textDirection: widget.textDirection, align: _getTextAlign(), strutStyle: StrutStyle.fromTextStyle(style), ); From 09fb1d63074a1e3dba9c2f5120e594f845794934 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Mon, 28 Oct 2024 14:09:08 -0400 Subject: [PATCH 092/113] Remove unnecessary manual positioning of placeholder --- lib/src/editor/widgets/text/text_line.dart | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 6847949ea..c9b1d8efc 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -296,9 +296,6 @@ class _TextLineState extends State { } if (nodes.isEmpty && kIsWeb && addWebNodeIfNeeded) { nodes = LinkedList()..add(leaf.QuillText('\u{200B}')); - } else if(nodes.isEmpty && widget.line.style.containsKey('header')){ - lineStyle = lineStyle.copyWith(color: defaultStyles.placeHolder?.style.color); - nodes = LinkedList()..add(leaf.QuillText('Header Placeholder')); } final isComposingRangeOutOfLine = !widget.composingRange.isValid || @@ -770,8 +767,6 @@ class EditableTextLine extends RenderObjectWidget { color, cursorCont, inlineCodeStyle, - composingRange, - composingColor, cursorParagrahPlaceholderConfiguration, ); } From c4085229475ce3e393ba645af1fcab36444fa46c Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Mon, 28 Oct 2024 14:13:00 -0400 Subject: [PATCH 093/113] Chore: remove print call and unnecessary import --- lib/src/editor/editor.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 0eceeacfc..f9e4a0605 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -33,7 +33,6 @@ import 'widgets/box.dart'; import 'widgets/cursor.dart'; import 'widgets/delegate.dart'; import 'widgets/float_cursor.dart'; -import 'widgets/text/text_line.dart'; import 'widgets/text/text_selection.dart'; /// Base interface for editable render objects. @@ -1098,9 +1097,6 @@ class RenderEditor extends RenderEditableContainerBox }) { final fromPosition = getPositionForOffset(from); final toPosition = to == null ? null : getPositionForOffset(to); - final child = childAtPosition(toPosition ?? fromPosition); - print(child as RenderEditableTextLine); - print(child.line); var baseOffset = fromPosition.offset; var extentOffset = fromPosition.offset; From 5b7b65a6b69954cd997a3b78f3c61e81cfeaa619 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Mon, 28 Oct 2024 14:39:32 -0400 Subject: [PATCH 094/113] Chore: dart format --- .../Flutter/GeneratedPluginRegistrant.swift | 2 +- .../lib/flutter_quill_extensions.dart | 2 -- .../clipboard/super_clipboard_service.dart | 2 -- .../placeholder_builder_internal.dart | 2 +- .../editor/raw_editor/raw_editor_state.dart | 1 - lib/src/editor/widgets/text/text_line.dart | 22 +++++++++---------- 6 files changed, 13 insertions(+), 18 deletions(-) diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index 10abb57dc..988945165 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -13,7 +13,7 @@ import irondash_engine_context import path_provider_foundation import quill_native_bridge_macos import share_plus -import sqflite_darwin +import sqflite import super_native_extensions import url_launcher_macos import video_player_avfoundation diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index e36dce9e1..3356edf79 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -1,7 +1,5 @@ library; -import 'package:flutter_quill/flutter_quill_internal.dart' - show ClipboardServiceProvider; import 'package:meta/meta.dart' show experimental; import 'src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart'; diff --git a/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart b/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart index 51466ff61..63cdeb747 100644 --- a/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart +++ b/flutter_quill_extensions/lib/src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart @@ -2,8 +2,6 @@ import 'dart:async' show Completer; import 'dart:convert' show utf8; import 'package:flutter/foundation.dart'; -import 'package:flutter_quill/flutter_quill_internal.dart' - show ClipboardService; import 'package:meta/meta.dart' show experimental; import 'package:super_clipboard/super_clipboard.dart'; diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 2b5166e7d..2fe93eae3 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -78,8 +78,8 @@ class PlaceholderBuilder { WidgetSpan? build({ required Attribute blockAttribute, required TextStyle lineStyle, - TextDirection? textDirection, required TextAlign align, + TextDirection? textDirection, StrutStyle? strutStyle, }) { if (builders.isEmpty) return null; diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 032cf3906..2f1e3d050 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -25,7 +25,6 @@ import '../../document/nodes/block.dart'; import '../../document/nodes/embeddable.dart'; import '../../document/nodes/line.dart'; import '../../document/nodes/node.dart'; -import '../../document/style.dart'; import '../../editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; import '../editor.dart'; import '../widgets/cursor.dart'; diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index c9b1d8efc..e66ef91cb 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -757,17 +757,17 @@ class EditableTextLine extends RenderObjectWidget { @override RenderObject createRenderObject(BuildContext context) { return RenderEditableTextLine( - line, - textDirection, - textSelection, - enableInteractiveSelection, - hasFocus, - devicePixelRatio, - _getPadding(), - color, - cursorCont, - inlineCodeStyle, - cursorParagrahPlaceholderConfiguration, + line, + textDirection, + textSelection, + enableInteractiveSelection, + hasFocus, + devicePixelRatio, + _getPadding(), + color, + cursorCont, + inlineCodeStyle, + cursorParagrahPlaceholderConfiguration, ); } From 4bbd064a201c81b38f5962d4fb759559a842bbaf Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 01:43:52 -0400 Subject: [PATCH 095/113] Chore: dart formatting --- lib/src/editor/editor.dart | 300 ++++++++++++------ .../raw_editor/config/raw_editor_config.dart | 1 + .../editor/raw_editor/raw_editor_state.dart | 142 ++++++--- 3 files changed, 301 insertions(+), 142 deletions(-) diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index dc5b79f4e..b42977915 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -1,6 +1,7 @@ import 'dart:math' as math; -import 'package:flutter/cupertino.dart' show CupertinoTheme, cupertinoTextSelectionControls; +import 'package:flutter/cupertino.dart' + show CupertinoTheme, cupertinoTextSelectionControls; import 'package:flutter/foundation.dart' show ValueListenable, kIsWeb; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -55,14 +56,15 @@ abstract class RenderAbstractEditor implements TextLayoutMetrics { /// and the returned list is of length two. In this case, however, the two /// points might actually be co-located (e.g., because of a bidirectional /// selection that contains some text but whose ends meet in the middle). - List getEndpointsForSelection(TextSelection textSelection); + List getEndpointsForSelection( + TextSelection textSelection); /// Sets the screen position of the floating cursor and the text position /// closest to the cursor. /// `resetLerpValue` drives the size of the floating cursor. /// See [EditorState.floatingCursorResetController]. - void setFloatingCursor( - FloatingCursorDragState dragState, Offset lastBoundedOffset, TextPosition lastTextPosition, + void setFloatingCursor(FloatingCursorDragState dragState, + Offset lastBoundedOffset, TextPosition lastTextPosition, {double? resetLerpValue}); /// If [ignorePointer] is false (the default) then this method is called by @@ -95,7 +97,8 @@ abstract class RenderAbstractEditor implements TextLayoutMetrics { /// yet reflected in the latest widget state. /// /// Returns null if no change occurred. - TextSelection? selectPositionAt({required Offset from, required SelectionChangedCause cause, Offset? to}); + TextSelection? selectPositionAt( + {required Offset from, required SelectionChangedCause cause, Offset? to}); /// Select a word around the location of the last tap down. /// @@ -182,9 +185,11 @@ class QuillEditor extends StatefulWidget { QuillEditorState createState() => QuillEditorState(); } -class QuillEditorState extends State implements EditorTextSelectionGestureDetectorBuilderDelegate { +class QuillEditorState extends State + implements EditorTextSelectionGestureDetectorBuilderDelegate { late GlobalKey _editorKey; - late EditorTextSelectionGestureDetectorBuilder _selectionGestureDetectorBuilder; + late EditorTextSelectionGestureDetectorBuilder + _selectionGestureDetectorBuilder; QuillController get controller => widget.controller; @@ -194,7 +199,8 @@ class QuillEditorState extends State implements EditorTextSelection void initState() { super.initState(); _editorKey = configurations.editorKey ?? GlobalKey(); - _selectionGestureDetectorBuilder = _QuillEditorSelectionGestureDetectorBuilder( + _selectionGestureDetectorBuilder = + _QuillEditorSelectionGestureDetectorBuilder( this, configurations.detectWordBoundary, ); @@ -216,7 +222,8 @@ class QuillEditorState extends State implements EditorTextSelection @override Widget build(BuildContext context) { final theme = Theme.of(context); - final selectionTheme = configurations.textSelectionThemeData ?? TextSelectionTheme.of(context); + final selectionTheme = + configurations.textSelectionThemeData ?? TextSelectionTheme.of(context); TextSelectionControls textSelectionControls; bool paintCursorAboveText; @@ -232,29 +239,36 @@ class QuillEditorState extends State implements EditorTextSelection paintCursorAboveText = true; cursorOpacityAnimates = true; cursorColor ??= selectionTheme.cursorColor ?? cupertinoTheme.primaryColor; - selectionColor = selectionTheme.selectionColor ?? cupertinoTheme.primaryColor.withOpacity(0.40); + selectionColor = selectionTheme.selectionColor ?? + cupertinoTheme.primaryColor.withOpacity(0.40); cursorRadius ??= const Radius.circular(2); - cursorOffset = Offset(iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + cursorOffset = Offset( + iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); } else { textSelectionControls = materialTextSelectionControls; paintCursorAboveText = false; cursorOpacityAnimates = false; cursorColor ??= selectionTheme.cursorColor ?? theme.colorScheme.primary; - selectionColor = selectionTheme.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40); - } - - final showSelectionToolbar = - configurations.enableInteractiveSelection && configurations.enableSelectionToolbar; - final placeholderBuilder = widget.config.placeholderComponentsConfiguration == null - ? null - : PlaceholderBuilder(configuration: widget.config.placeholderComponentsConfiguration!); + selectionColor = selectionTheme.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + } + + final showSelectionToolbar = configurations.enableInteractiveSelection && + configurations.enableSelectionToolbar; + final placeholderBuilder = + widget.config.placeholderComponentsConfiguration == null + ? null + : PlaceholderBuilder( + configuration: + widget.config.placeholderComponentsConfiguration!); final child = QuillRawEditor( key: _editorKey, controller: controller, config: QuillRawEditorConfig( characterShortcutEvents: widget.config.characterShortcutEvents, spaceShortcutEvents: widget.config.spaceShortcutEvents, - cursorParagrahPlaceholderConfiguration: widget.config.cursorParagrahPlaceholderConfiguration, + cursorParagrahPlaceholderConfiguration: + widget.config.cursorParagrahPlaceholderConfiguration, placeholderBuilder: placeholderBuilder, onKeyPressed: widget.config.onKeyPressed, customLeadingBuilder: widget.config.customLeadingBlockBuilder, @@ -270,7 +284,8 @@ class QuillEditorState extends State implements EditorTextSelection placeholder: configurations.placeholder, onLaunchUrl: configurations.onLaunchUrl, contextMenuBuilder: showSelectionToolbar - ? (configurations.contextMenuBuilder ?? QuillRawEditorConfig.defaultContextMenuBuilder) + ? (configurations.contextMenuBuilder ?? + QuillRawEditorConfig.defaultContextMenuBuilder) : null, showSelectionHandles: isMobile, showCursor: configurations.showCursor ?? true, @@ -280,7 +295,8 @@ class QuillEditorState extends State implements EditorTextSelection width: 2, radius: cursorRadius, offset: cursorOffset, - paintAboveText: configurations.paintCursorAboveText ?? paintCursorAboveText, + paintAboveText: + configurations.paintCursorAboveText ?? paintCursorAboveText, opacityAnimates: cursorOpacityAnimates, ), textCapitalization: configurations.textCapitalization, @@ -291,7 +307,8 @@ class QuillEditorState extends State implements EditorTextSelection expands: configurations.expands, autoFocus: configurations.autoFocus, selectionColor: selectionColor, - selectionCtrls: configurations.textSelectionControls ?? textSelectionControls, + selectionCtrls: + configurations.textSelectionControls ?? textSelectionControls, keyboardAppearance: configurations.keyboardAppearance, enableInteractiveSelection: configurations.enableInteractiveSelection, scrollPhysics: configurations.scrollPhysics, @@ -306,7 +323,8 @@ class QuillEditorState extends State implements EditorTextSelection onTapOutsideEnabled: configurations.onTapOutsideEnabled, onTapOutside: configurations.onTapOutside, dialogTheme: configurations.dialogTheme, - contentInsertionConfiguration: configurations.contentInsertionConfiguration, + contentInsertionConfiguration: + configurations.contentInsertionConfiguration, enableScribble: configurations.enableScribble, onScribbleActivated: configurations.onScribbleActivated, scribbleAreaInsets: configurations.scribbleAreaInsets, @@ -392,8 +410,10 @@ class QuillEditorState extends State implements EditorTextSelection } } -class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGestureDetectorBuilder { - _QuillEditorSelectionGestureDetectorBuilder(this._state, this._detectWordBoundary) +class _QuillEditorSelectionGestureDetectorBuilder + extends EditorTextSelectionGestureDetectorBuilder { + _QuillEditorSelectionGestureDetectorBuilder( + this._state, this._detectWordBoundary) : super(delegate: _state, detectWordBoundary: _detectWordBoundary); final QuillEditorState _state; @@ -445,7 +465,8 @@ class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGes return false; } final pos = renderEditor!.getPositionForOffset(details.globalPosition); - final result = editor!.widget.controller.document.querySegmentLeafNode(pos.offset); + final result = + editor!.widget.controller.document.querySegmentLeafNode(pos.offset); final line = result.line; if (line == null) { return false; @@ -478,7 +499,8 @@ class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGes bool isShiftClick(PointerDeviceKind deviceKind) { final pressed = HardwareKeyboard.instance.logicalKeysPressed; return deviceKind == PointerDeviceKind.mouse && - (pressed.contains(LogicalKeyboardKey.shiftLeft) || pressed.contains(LogicalKeyboardKey.shiftRight)); + (pressed.contains(LogicalKeyboardKey.shiftLeft) || + pressed.contains(LogicalKeyboardKey.shiftRight)); } @override @@ -507,7 +529,8 @@ class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGes // extend current selection instead. if (isShiftClick(details.kind)) { renderEditor! - ..extendSelection(details.globalPosition, cause: SelectionChangedCause.tap) + ..extendSelection(details.globalPosition, + cause: SelectionChangedCause.tap) ..onSelectionCompleted(); } else { renderEditor! @@ -609,7 +632,8 @@ class _QuillEditorSelectionGestureDetectorBuilder extends EditorTextSelectionGes /// (including the cursor location). /// /// Used by [RenderEditor.onSelectionChanged]. -typedef TextSelectionChangedHandler = void Function(TextSelection selection, SelectionChangedCause cause); +typedef TextSelectionChangedHandler = void Function( + TextSelection selection, SelectionChangedCause cause); /// Signature for the callback that reports when a selection action is actually /// completed and ratified. Completion is defined as when the user input has @@ -628,7 +652,8 @@ const EdgeInsets _kFloatingCursorAddedMargin = EdgeInsets.fromLTRB(4, 4, 4, 5); // The additional size on the x and y axis with which to expand the prototype // cursor to render the floating cursor in pixels. -const EdgeInsets _kFloatingCaretSizeIncrease = EdgeInsets.symmetric(horizontal: 0.5, vertical: 1); +const EdgeInsets _kFloatingCaretSizeIncrease = + EdgeInsets.symmetric(horizontal: 0.5, vertical: 1); /// Displays a document as a vertical list of document segments (lines /// and blocks). @@ -653,7 +678,8 @@ class RenderEditor extends RenderEditableContainerBox required this.floatingCursorDisabled, ViewportOffset? offset, super.children, - EdgeInsets floatingCursorAddedMargin = const EdgeInsets.fromLTRB(4, 4, 4, 5), + EdgeInsets floatingCursorAddedMargin = + const EdgeInsets.fromLTRB(4, 4, 4, 5), double? maxContentWidth, }) : _hasFocus = hasFocus, _extendSelectionOrigin = selection, @@ -679,16 +705,19 @@ class RenderEditor extends RenderEditableContainerBox /// Called when the selection changes. TextSelectionChangedHandler onSelectionChanged; TextSelectionCompletedHandler onSelectionCompleted; - final ValueNotifier _selectionStartInViewport = ValueNotifier(true); + final ValueNotifier _selectionStartInViewport = + ValueNotifier(true); - ValueListenable get selectionStartInViewport => _selectionStartInViewport; + ValueListenable get selectionStartInViewport => + _selectionStartInViewport; ValueListenable get selectionEndInViewport => _selectionEndInViewport; final ValueNotifier _selectionEndInViewport = ValueNotifier(true); void _updateSelectionExtentsVisibility(Offset effectiveOffset) { final visibleRegion = Offset.zero & size; - final startPosition = TextPosition(offset: selection.start, affinity: selection.affinity); + final startPosition = + TextPosition(offset: selection.start, affinity: selection.affinity); final startOffset = _getOffsetForCaret(startPosition); // TODO(justinmc): https://github.com/flutter/flutter/issues/31495 // Check if the selection is visible with an approximation because a @@ -698,12 +727,16 @@ class RenderEditor extends RenderEditableContainerBox // _applyFloatingPointHack. Ideally, the rounding mismatch will be fixed and // this can be changed to be a strict check instead of an approximation. const visibleRegionSlop = 0.5; - _selectionStartInViewport.value = - visibleRegion.inflate(visibleRegionSlop).contains(startOffset + effectiveOffset); + _selectionStartInViewport.value = visibleRegion + .inflate(visibleRegionSlop) + .contains(startOffset + effectiveOffset); - final endPosition = TextPosition(offset: selection.end, affinity: selection.affinity); + final endPosition = + TextPosition(offset: selection.end, affinity: selection.affinity); final endOffset = _getOffsetForCaret(endPosition); - _selectionEndInViewport.value = visibleRegion.inflate(visibleRegionSlop).contains(endOffset + effectiveOffset); + _selectionEndInViewport.value = visibleRegion + .inflate(visibleRegionSlop) + .contains(endOffset + effectiveOffset); } // returns offset relative to this at which the caret will be painted @@ -760,8 +793,10 @@ class RenderEditor extends RenderEditableContainerBox } bool get _shiftPressed => - HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.shiftLeft) || - HardwareKeyboard.instance.logicalKeysPressed.contains(LogicalKeyboardKey.shiftRight); + HardwareKeyboard.instance.logicalKeysPressed + .contains(LogicalKeyboardKey.shiftLeft) || + HardwareKeyboard.instance.logicalKeysPressed + .contains(LogicalKeyboardKey.shiftRight); void setStartHandleLayerLink(LayerLink value) { if (_startHandleLayerLink == value) { @@ -796,7 +831,8 @@ class RenderEditor extends RenderEditableContainerBox } @override - List getEndpointsForSelection(TextSelection textSelection) { + List getEndpointsForSelection( + TextSelection textSelection) { if (textSelection.isCollapsed) { final child = childAtPosition(textSelection.extent); final localPosition = TextPosition( @@ -807,7 +843,10 @@ class RenderEditor extends RenderEditableContainerBox final parentData = child.parentData as BoxParentData; return [ TextSelectionPoint( - Offset(0, child.preferredLineHeight(localPosition)) + localOffset + parentData.offset, null) + Offset(0, child.preferredLineHeight(localPosition)) + + localOffset + + parentData.offset, + null) ]; } @@ -823,7 +862,8 @@ class RenderEditor extends RenderEditableContainerBox assert(baseChild != null); final baseParentData = baseChild!.parentData as BoxParentData; - final baseSelection = localSelection(baseChild.container, textSelection, true); + final baseSelection = + localSelection(baseChild.container, textSelection, true); var basePoint = baseChild.getBaseEndpointForSelection(baseSelection); basePoint = TextSelectionPoint( basePoint.point + baseParentData.offset, @@ -852,8 +892,10 @@ class RenderEditor extends RenderEditableContainerBox assert(extentChild != null); final extentParentData = extentChild!.parentData as BoxParentData; - final extentSelection = localSelection(extentChild.container, textSelection, true); - var extentPoint = extentChild.getExtentEndpointForSelection(extentSelection); + final extentSelection = + localSelection(extentChild.container, textSelection, true); + var extentPoint = + extentChild.getExtentEndpointForSelection(extentSelection); extentPoint = TextSelectionPoint( extentPoint.point + extentParentData.offset, extentPoint.direction, @@ -910,7 +952,8 @@ class RenderEditor extends RenderEditableContainerBox ) { final firstPosition = getPositionForOffset(from); final firstWord = selectWordAtPosition(firstPosition); - final lastWord = to == null ? firstWord : selectWordAtPosition(getPositionForOffset(to)); + final lastWord = + to == null ? firstWord : selectWordAtPosition(getPositionForOffset(to)); _handleSelectionChange( TextSelection( @@ -926,8 +969,12 @@ class RenderEditor extends RenderEditableContainerBox TextSelection nextSelection, SelectionChangedCause cause, ) { - final focusingEmpty = nextSelection.baseOffset == 0 && nextSelection.extentOffset == 0 && !_hasFocus; - if (nextSelection == selection && cause != SelectionChangedCause.keyboard && !focusingEmpty) { + final focusingEmpty = nextSelection.baseOffset == 0 && + nextSelection.extentOffset == 0 && + !_hasFocus; + if (nextSelection == selection && + cause != SelectionChangedCause.keyboard && + !focusingEmpty) { return; } onSelectionChanged(nextSelection, cause); @@ -978,7 +1025,8 @@ class RenderEditor extends RenderEditableContainerBox ); // Don't change selection if the selected word is a placeholder. - if (child.container.style.attributes.containsKey(Attribute.placeholder.key)) { + if (child.container.style.attributes + .containsKey(Attribute.placeholder.key)) { return; } @@ -989,7 +1037,8 @@ class RenderEditor extends RenderEditableContainerBox ); } else { _handleSelectionChange( - TextSelection.collapsed(offset: word.end, affinity: TextAffinity.upstream), + TextSelection.collapsed( + offset: word.end, affinity: TextAffinity.upstream), cause, ); } @@ -1064,7 +1113,8 @@ class RenderEditor extends RenderEditableContainerBox ' resize its children, so it must be ' 'placed in a parent that does not constrain the main ' 'axis.'), - ErrorHint('You probably want to put the RenderEditableContainerBox inside a ' + ErrorHint( + 'You probably want to put the RenderEditableContainerBox inside a ' 'RenderViewport with a matching main axis or disable the ' 'scrollable property.') ]); @@ -1086,11 +1136,13 @@ class RenderEditor extends RenderEditableContainerBox var mainAxisExtent = resolvedPadding!.top; var child = firstChild; - final innerConstraints = - BoxConstraints.tightFor(width: math.min(_maxContentWidth ?? double.infinity, constraints.maxWidth)) - .deflate(resolvedPadding!); - final leftOffset = - _maxContentWidth == null ? 0.0 : math.max((constraints.maxWidth - _maxContentWidth!) / 2, 0); + final innerConstraints = BoxConstraints.tightFor( + width: math.min( + _maxContentWidth ?? double.infinity, constraints.maxWidth)) + .deflate(resolvedPadding!); + final leftOffset = _maxContentWidth == null + ? 0.0 + : math.max((constraints.maxWidth - _maxContentWidth!) / 2, 0); while (child != null) { child.layout(innerConstraints, parentUsesSize: true); final childParentData = child.parentData as EditableContainerParentData @@ -1107,14 +1159,18 @@ class RenderEditor extends RenderEditableContainerBox @override void paint(PaintingContext context, Offset offset) { - if (_hasFocus && _cursorController.show.value && !_cursorController.style.paintAboveText) { + if (_hasFocus && + _cursorController.show.value && + !_cursorController.style.paintAboveText) { _paintFloatingCursor(context, offset); } defaultPaint(context, offset); _updateSelectionExtentsVisibility(offset + _paintOffset); _paintHandleLayers(context, getEndpointsForSelection(selection)); - if (_hasFocus && _cursorController.show.value && _cursorController.style.paintAboveText) { + if (_hasFocus && + _cursorController.show.value && + _cursorController.style.paintAboveText) { _paintFloatingCursor(context, offset); } } @@ -1124,7 +1180,8 @@ class RenderEditor extends RenderEditableContainerBox return defaultHitTestChildren(result, position: position); } - void _paintHandleLayers(PaintingContext context, List endpoints) { + void _paintHandleLayers( + PaintingContext context, List endpoints) { var startPoint = endpoints[0].point; startPoint = Offset( startPoint.dx.clamp(0.0, size.width), @@ -1152,7 +1209,8 @@ class RenderEditor extends RenderEditableContainerBox @override double preferredLineHeight(TextPosition position) { final child = childAtPosition(position); - return child.preferredLineHeight(TextPosition(offset: position.offset - child.container.offset)); + return child.preferredLineHeight( + TextPosition(offset: position.offset - child.container.offset)); } @override @@ -1187,7 +1245,8 @@ class RenderEditor extends RenderEditableContainerBox /// this editor from above it. /// /// Returns `null` if the cursor is currently visible. - double? getOffsetToRevealCursor(double viewportHeight, double scrollOffset, double offsetInViewport) { + double? getOffsetToRevealCursor( + double viewportHeight, double scrollOffset, double offsetInViewport) { // Endpoints coordinates represents lower left or lower right corner of // the selection. If we want to scroll up to reveal the caret we need to // adjust the dy value by the height of the line. We also add a small margin @@ -1200,7 +1259,9 @@ class RenderEditor extends RenderEditableContainerBox endpoint = endpoints.first; } else { if (selection is DragTextSelection) { - endpoint = (selection as DragTextSelection).first ? endpoints.first : endpoints.last; + endpoint = (selection as DragTextSelection).first + ? endpoints.first + : endpoints.last; } else { endpoint = endpoints.first; } @@ -1211,11 +1272,13 @@ class RenderEditor extends RenderEditableContainerBox const kMargin = 8.0; final caretTop = endpoint.point.dy - - child.preferredLineHeight(TextPosition(offset: selection.extentOffset - child.container.documentOffset)) - + child.preferredLineHeight(TextPosition( + offset: selection.extentOffset - child.container.documentOffset)) - kMargin + offsetInViewport + scrollBottomInset; - final caretBottom = endpoint.point.dy + kMargin + offsetInViewport + scrollBottomInset; + final caretBottom = + endpoint.point.dy + kMargin + offsetInViewport + scrollBottomInset; double? dy; if (caretTop < scrollOffset) { dy = caretTop; @@ -1265,10 +1328,12 @@ class RenderEditor extends RenderEditableContainerBox bool _resetOriginOnBottom = false; /// Returns the position within the editor closest to the raw cursor offset. - Offset calculateBoundedFloatingCursorOffset(Offset rawCursorOffset, double preferredLineHeight) { + Offset calculateBoundedFloatingCursorOffset( + Offset rawCursorOffset, double preferredLineHeight) { var deltaPosition = Offset.zero; final topBound = _kFloatingCursorAddedMargin.top; - final bottomBound = size.height - preferredLineHeight + _kFloatingCursorAddedMargin.bottom; + final bottomBound = + size.height - preferredLineHeight + _kFloatingCursorAddedMargin.bottom; final leftBound = _kFloatingCursorAddedMargin.left; final rightBound = size.width - _kFloatingCursorAddedMargin.right; @@ -1280,24 +1345,30 @@ class RenderEditor extends RenderEditableContainerBox // we want to reset the relative origin of // the dragging when the user drags back into the field. if (_resetOriginOnLeft && deltaPosition.dx > 0) { - _relativeOrigin = Offset(rawCursorOffset.dx - leftBound, _relativeOrigin.dy); + _relativeOrigin = + Offset(rawCursorOffset.dx - leftBound, _relativeOrigin.dy); _resetOriginOnLeft = false; } else if (_resetOriginOnRight && deltaPosition.dx < 0) { - _relativeOrigin = Offset(rawCursorOffset.dx - rightBound, _relativeOrigin.dy); + _relativeOrigin = + Offset(rawCursorOffset.dx - rightBound, _relativeOrigin.dy); _resetOriginOnRight = false; } if (_resetOriginOnTop && deltaPosition.dy > 0) { - _relativeOrigin = Offset(_relativeOrigin.dx, rawCursorOffset.dy - topBound); + _relativeOrigin = + Offset(_relativeOrigin.dx, rawCursorOffset.dy - topBound); _resetOriginOnTop = false; } else if (_resetOriginOnBottom && deltaPosition.dy < 0) { - _relativeOrigin = Offset(_relativeOrigin.dx, rawCursorOffset.dy - bottomBound); + _relativeOrigin = + Offset(_relativeOrigin.dx, rawCursorOffset.dy - bottomBound); _resetOriginOnBottom = false; } final currentX = rawCursorOffset.dx - _relativeOrigin.dx; final currentY = rawCursorOffset.dy - _relativeOrigin.dy; - final double adjustedX = math.min(math.max(currentX, leftBound), rightBound); - final double adjustedY = math.min(math.max(currentY, topBound), bottomBound); + final double adjustedX = + math.min(math.max(currentX, leftBound), rightBound); + final double adjustedY = + math.min(math.max(currentY, topBound), bottomBound); final adjustedOffset = Offset(adjustedX, adjustedY); if (currentX < leftBound && deltaPosition.dx < 0) { @@ -1317,7 +1388,8 @@ class RenderEditor extends RenderEditableContainerBox } @override - void setFloatingCursor(FloatingCursorDragState dragState, Offset boundedOffset, TextPosition textPosition, + void setFloatingCursor(FloatingCursorDragState dragState, + Offset boundedOffset, TextPosition textPosition, {double? resetLerpValue}) { if (floatingCursorDisabled) return; @@ -1333,13 +1405,17 @@ class RenderEditor extends RenderEditableContainerBox if (_floatingCursorOn) { _floatingCursorTextPosition = textPosition; final sizeAdjustment = resetLerpValue != null - ? EdgeInsets.lerp(_kFloatingCaretSizeIncrease, EdgeInsets.zero, resetLerpValue)! + ? EdgeInsets.lerp( + _kFloatingCaretSizeIncrease, EdgeInsets.zero, resetLerpValue)! : _kFloatingCaretSizeIncrease; final child = childAtPosition(textPosition); - final caretPrototype = child.getCaretPrototype(child.globalToLocalPosition(textPosition)); - _floatingCursorRect = sizeAdjustment.inflateRect(caretPrototype).shift(boundedOffset); + final caretPrototype = + child.getCaretPrototype(child.globalToLocalPosition(textPosition)); + _floatingCursorRect = + sizeAdjustment.inflateRect(caretPrototype).shift(boundedOffset); - _cursorController.setFloatingCursorTextPosition(_floatingCursorTextPosition); + _cursorController + .setFloatingCursorTextPosition(_floatingCursorTextPosition); } else { _floatingCursorRect = null; _cursorController.setFloatingCursorTextPosition(null); @@ -1360,7 +1436,8 @@ class RenderEditor extends RenderEditableContainerBox TextSelection getLineAtOffset(TextPosition position) { final child = childAtPosition(position); final nodeOffset = child.container.offset; - final localPosition = TextPosition(offset: position.offset - nodeOffset, affinity: position.affinity); + final localPosition = TextPosition( + offset: position.offset - nodeOffset, affinity: position.affinity); final localLineRange = child.getLineBoundary(localPosition); final line = TextRange( start: localLineRange.start + nodeOffset, @@ -1373,7 +1450,8 @@ class RenderEditor extends RenderEditableContainerBox TextRange getWordBoundary(TextPosition position) { final child = childAtPosition(position); final nodeOffset = child.container.offset; - final localPosition = TextPosition(offset: position.offset - nodeOffset, affinity: position.affinity); + final localPosition = TextPosition( + offset: position.offset - nodeOffset, affinity: position.affinity); final localWord = child.getWordBoundary(localPosition); return TextRange( start: localWord.start + nodeOffset, @@ -1382,7 +1460,8 @@ class RenderEditor extends RenderEditableContainerBox } /// Returns the TextPosition after moving by the vertical offset. - TextPosition getTextPositionMoveVertical(TextPosition position, double verticalOffset) { + TextPosition getTextPositionMoveVertical( + TextPosition position, double verticalOffset) { final caretOfs = localToGlobal(_getOffsetForCaret(position)); return getPositionForOffset(caretOfs.translate(0, verticalOffset)); } @@ -1394,7 +1473,8 @@ class RenderEditor extends RenderEditableContainerBox @override TextPosition getTextPositionAbove(TextPosition position) { final child = childAtPosition(position); - final localPosition = TextPosition(offset: position.offset - child.container.documentOffset); + final localPosition = + TextPosition(offset: position.offset - child.container.documentOffset); var newPosition = child.getPositionAbove(localPosition); @@ -1412,10 +1492,12 @@ class RenderEditor extends RenderEditableContainerBox final testOffset = sibling.getOffsetForCaret(testPosition); final finalOffset = Offset(caretOffset.dx, testOffset.dy); final siblingPosition = sibling.getPositionForOffset(finalOffset); - newPosition = TextPosition(offset: sibling.container.documentOffset + siblingPosition.offset); + newPosition = TextPosition( + offset: sibling.container.documentOffset + siblingPosition.offset); } } else { - newPosition = TextPosition(offset: child.container.documentOffset + newPosition.offset); + newPosition = TextPosition( + offset: child.container.documentOffset + newPosition.offset); } return newPosition; } @@ -1460,7 +1542,8 @@ class RenderEditor extends RenderEditableContainerBox // End TextLayoutMetrics implementation - QuillVerticalCaretMovementRun startVerticalCaretMovement(TextPosition startPosition) { + QuillVerticalCaretMovementRun startVerticalCaretMovement( + TextPosition startPosition) { return QuillVerticalCaretMovementRun._( this, startPosition, @@ -1501,19 +1584,23 @@ class QuillVerticalCaretMovementRun implements Iterator { } void moveVertical(double verticalOffset) { - _currentTextPosition = _editor.getTextPositionMoveVertical(_currentTextPosition, verticalOffset); + _currentTextPosition = _editor.getTextPositionMoveVertical( + _currentTextPosition, verticalOffset); } } -class EditableContainerParentData extends ContainerBoxParentData {} +class EditableContainerParentData + extends ContainerBoxParentData {} /// Multi-child render box of editable content. /// /// Common ancestor for [RenderEditor] and [RenderEditableTextBlock]. class RenderEditableContainerBox extends RenderBox with - ContainerRenderObjectMixin, - RenderBoxContainerDefaultsMixin { + ContainerRenderObjectMixin, + RenderBoxContainerDefaultsMixin { RenderEditableContainerBox({ required container_node.QuillContainer container, required this.textDirection, @@ -1642,7 +1729,9 @@ class RenderEditableContainerBox extends RenderBox var mainAxisExtent = _resolvedPadding!.top; var child = firstChild; - final innerConstraints = BoxConstraints.tightFor(width: constraints.maxWidth).deflate(_resolvedPadding!); + final innerConstraints = + BoxConstraints.tightFor(width: constraints.maxWidth) + .deflate(_resolvedPadding!); while (child != null) { child.layout(innerConstraints, parentUsesSize: true); final childParentData = (child.parentData as EditableContainerParentData) @@ -1683,8 +1772,11 @@ class RenderEditableContainerBox extends RenderBox double computeMinIntrinsicWidth(double height) { resolvePadding(); return _getIntrinsicCrossAxis((child) { - final childHeight = math.max(0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); - return child.getMinIntrinsicWidth(childHeight) + _resolvedPadding!.left + _resolvedPadding!.right; + final childHeight = math.max( + 0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); + return child.getMinIntrinsicWidth(childHeight) + + _resolvedPadding!.left + + _resolvedPadding!.right; }); } @@ -1692,8 +1784,11 @@ class RenderEditableContainerBox extends RenderBox double computeMaxIntrinsicWidth(double height) { resolvePadding(); return _getIntrinsicCrossAxis((child) { - final childHeight = math.max(0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); - return child.getMaxIntrinsicWidth(childHeight) + _resolvedPadding!.left + _resolvedPadding!.right; + final childHeight = math.max( + 0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); + return child.getMaxIntrinsicWidth(childHeight) + + _resolvedPadding!.left + + _resolvedPadding!.right; }); } @@ -1701,8 +1796,11 @@ class RenderEditableContainerBox extends RenderBox double computeMinIntrinsicHeight(double width) { resolvePadding(); return _getIntrinsicMainAxis((child) { - final childWidth = math.max(0, width - _resolvedPadding!.left + _resolvedPadding!.right); - return child.getMinIntrinsicHeight(childWidth) + _resolvedPadding!.top + _resolvedPadding!.bottom; + final childWidth = math.max( + 0, width - _resolvedPadding!.left + _resolvedPadding!.right); + return child.getMinIntrinsicHeight(childWidth) + + _resolvedPadding!.top + + _resolvedPadding!.bottom; }); } @@ -1710,14 +1808,18 @@ class RenderEditableContainerBox extends RenderBox double computeMaxIntrinsicHeight(double width) { resolvePadding(); return _getIntrinsicMainAxis((child) { - final childWidth = math.max(0, width - _resolvedPadding!.left + _resolvedPadding!.right); - return child.getMaxIntrinsicHeight(childWidth) + _resolvedPadding!.top + _resolvedPadding!.bottom; + final childWidth = math.max( + 0, width - _resolvedPadding!.left + _resolvedPadding!.right); + return child.getMaxIntrinsicHeight(childWidth) + + _resolvedPadding!.top + + _resolvedPadding!.bottom; }); } @override double computeDistanceToActualBaseline(TextBaseline baseline) { resolvePadding(); - return defaultComputeDistanceToFirstActualBaseline(baseline)! + _resolvedPadding!.top; + return defaultComputeDistanceToFirstActualBaseline(baseline)! + + _resolvedPadding!.top; } } diff --git a/lib/src/editor/raw_editor/config/raw_editor_config.dart b/lib/src/editor/raw_editor/config/raw_editor_config.dart index e1ab8116a..e749b52a3 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_config.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_config.dart @@ -137,6 +137,7 @@ class QuillRawEditorConfig { /// This argument configure how will be showed the placeholder at right or left of the cursor final CursorParagrahPlaceholderConfiguration? cursorParagrahPlaceholderConfiguration; + /// A handler for keys that are pressed when the editor is focused. /// /// This feature is supported on **desktop devices only**. diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 5304337e0..6cbe27fd3 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -8,7 +8,8 @@ import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart' show RenderAbstractViewport; import 'package:flutter/scheduler.dart' show SchedulerBinding; -import 'package:flutter/services.dart' show Clipboard, HardwareKeyboard, SystemChannels, TextInputControl; +import 'package:flutter/services.dart' + show Clipboard, HardwareKeyboard, SystemChannels, TextInputControl; import 'package:flutter_keyboard_visibility_temp_fork/flutter_keyboard_visibility_temp_fork.dart' show KeyboardVisibilityController; @@ -96,8 +97,11 @@ class QuillRawEditorState extends EditorState @override void insertContent(KeyboardInsertedContent content) { - assert(widget.config.contentInsertionConfiguration?.allowedMimeTypes.contains(content.mimeType) ?? false); - widget.config.contentInsertionConfiguration?.onContentInserted.call(content); + assert(widget.config.contentInsertionConfiguration?.allowedMimeTypes + .contains(content.mimeType) ?? + false); + widget.config.contentInsertionConfiguration?.onContentInserted + .call(content); } /// Copy current selection to [Clipboard]. @@ -113,7 +117,8 @@ class QuillRawEditorState extends EditorState userUpdateTextEditingValue( TextEditingValue( text: textEditingValue.text, - selection: TextSelection.collapsed(offset: textEditingValue.selection.end), + selection: + TextSelection.collapsed(offset: textEditingValue.selection.end), ), SelectionChangedCause.toolbar, ); @@ -149,7 +154,8 @@ class QuillRawEditorState extends EditorState void selectAll(SelectionChangedCause cause) { userUpdateTextEditingValue( textEditingValue.copyWith( - selection: TextSelection(baseOffset: 0, extentOffset: textEditingValue.text.length), + selection: TextSelection( + baseOffset: 0, extentOffset: textEditingValue.text.length), ), cause, ); @@ -164,14 +170,27 @@ class QuillRawEditorState extends EditorState /// Copied from [EditableTextState]. List get contextMenuButtonItems { return EditableText.getEditableButtonItems( - clipboardStatus: (_clipboardStatus != null) ? _clipboardStatus!.value : null, - onCopy: copyEnabled ? () => copySelection(SelectionChangedCause.toolbar) : null, - onCut: cutEnabled ? () => cutSelection(SelectionChangedCause.toolbar) : null, - onPaste: pasteEnabled ? () => pasteText(SelectionChangedCause.toolbar) : null, - onSelectAll: selectAllEnabled ? () => selectAll(SelectionChangedCause.toolbar) : null, - onLookUp: lookUpEnabled ? () => lookUpSelection(SelectionChangedCause.toolbar) : null, - onSearchWeb: searchWebEnabled ? () => searchWebForSelection(SelectionChangedCause.toolbar) : null, - onShare: shareEnabled ? () => shareSelection(SelectionChangedCause.toolbar) : null, + clipboardStatus: + (_clipboardStatus != null) ? _clipboardStatus!.value : null, + onCopy: copyEnabled + ? () => copySelection(SelectionChangedCause.toolbar) + : null, + onCut: + cutEnabled ? () => cutSelection(SelectionChangedCause.toolbar) : null, + onPaste: + pasteEnabled ? () => pasteText(SelectionChangedCause.toolbar) : null, + onSelectAll: selectAllEnabled + ? () => selectAll(SelectionChangedCause.toolbar) + : null, + onLookUp: lookUpEnabled + ? () => lookUpSelection(SelectionChangedCause.toolbar) + : null, + onSearchWeb: searchWebEnabled + ? () => searchWebForSelection(SelectionChangedCause.toolbar) + : null, + onShare: shareEnabled + ? () => shareSelection(SelectionChangedCause.toolbar) + : null, onLiveTextInput: liveTextInputEnabled ? () {} : null, ); } @@ -265,8 +284,10 @@ class QuillRawEditorState extends EditorState ); } - final startCharacterRect = renderEditor.getLocalRectForCaret(selection.base); - final endCharacterRect = renderEditor.getLocalRectForCaret(selection.extent); + final startCharacterRect = + renderEditor.getLocalRectForCaret(selection.base); + final endCharacterRect = + renderEditor.getLocalRectForCaret(selection.extent); return QuillEditorGlyphHeights( startCharacterRect.height, endCharacterRect.height, @@ -314,8 +335,10 @@ class QuillRawEditorState extends EditorState return ScribbleFocusable( editorKey: _editorKey, enabled: widget.config.enableScribble && !widget.config.readOnly, - renderBoxForBounds: () => - context.findAncestorStateOfType()?.context.findRenderObject() as RenderBox?, + renderBoxForBounds: () => context + .findAncestorStateOfType() + ?.context + .findRenderObject() as RenderBox?, onScribbleFocus: (offset) { widget.config.focusNode.requestFocus(); widget.config.onScribbleActivated?.call(); @@ -335,10 +358,12 @@ class QuillRawEditorState extends EditorState final raw = widget.config.placeholder?.replaceAll(r'"', '\\"'); // get current block attributes applied to the first line even if it // is empty - final blockAttributesWithoutContent = doc.root.children.firstOrNull?.toDelta().first.attributes; + final blockAttributesWithoutContent = + doc.root.children.firstOrNull?.toDelta().first.attributes; // check if it has code block attribute to add '//' to give to the users // the feeling of this is really a block of code - final isCodeBlock = blockAttributesWithoutContent?.containsKey('code-block') ?? false; + final isCodeBlock = + blockAttributesWithoutContent?.containsKey('code-block') ?? false; // we add the block attributes at the same time as the placeholder to allow the editor to display them without removing // the placeholder (this is really awkward when everything is empty) final blockAttrInsertion = blockAttributesWithoutContent == null @@ -372,7 +397,8 @@ class QuillRawEditorState extends EditorState /// the scroll view with [BaselineProxy] which mimics the editor's /// baseline. // This implies that the first line has no styles applied to it. - final baselinePadding = EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.top); + final baselinePadding = + EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.top); child = BaselineProxy( textStyle: _styles!.paragraph!.style, padding: baselinePadding, @@ -383,10 +409,14 @@ class QuillRawEditorState extends EditorState child: CompositedTransformTarget( link: _toolbarLayerLink, child: MouseRegion( - cursor: widget.config.readOnly ? widget.config.readOnlyMouseCursor : SystemMouseCursors.text, + cursor: widget.config.readOnly + ? widget.config.readOnlyMouseCursor + : SystemMouseCursors.text, child: QuillRawEditorMultiChildRenderObject( key: _editorKey, - offset: _scrollController.hasClients ? _scrollController.position : null, + offset: _scrollController.hasClients + ? _scrollController.position + : null, document: doc, selection: controller.selection, hasFocus: _hasFocus, @@ -400,7 +430,8 @@ class QuillRawEditorState extends EditorState padding: widget.config.padding, maxContentWidth: widget.config.maxContentWidth, cursorController: _cursorCont, - floatingCursorDisabled: widget.config.floatingCursorDisabled, + floatingCursorDisabled: + widget.config.floatingCursorDisabled, children: _buildChildren(doc, context), ), ), @@ -413,7 +444,9 @@ class QuillRawEditorState extends EditorState link: _toolbarLayerLink, child: Semantics( child: MouseRegion( - cursor: widget.config.readOnly ? widget.config.readOnlyMouseCursor : SystemMouseCursors.text, + cursor: widget.config.readOnly + ? widget.config.readOnlyMouseCursor + : SystemMouseCursors.text, child: QuillRawEditorMultiChildRenderObject( key: _editorKey, document: doc, @@ -513,7 +546,8 @@ class QuillRawEditorState extends EditorState /// Updates the checkbox positioned at [offset] in document /// by changing its attribute according to [value]. void _handleCheckboxTap(int offset, bool value) { - final requestKeyboardFocusOnCheckListChanged = widget.config.requestKeyboardFocusOnCheckListChanged; + final requestKeyboardFocusOnCheckListChanged = + widget.config.requestKeyboardFocusOnCheckListChanged; if (!(widget.config.checkBoxReadOnly ?? widget.config.readOnly)) { _disableScrollControllerAnimateOnce = true; final currentSelection = controller.selection.copyWith(); @@ -527,7 +561,10 @@ class QuillRawEditorState extends EditorState // Checkbox tapping causes controller.selection to go to offset 0 // Stop toggling those two toolbar buttons - ..toolbarButtonToggler = {Attribute.list.key: attribute, Attribute.header.key: Attribute.header}; + ..toolbarButtonToggler = { + Attribute.list.key: attribute, + Attribute.header.key: Attribute.header + }; // Go back from offset 0 to current selection SchedulerBinding.instance.addPostFrameCallback((_) { @@ -553,7 +590,8 @@ class QuillRawEditorState extends EditorState for (final node in doc.root.children) { final attrs = node.style.attributes; - if (prevNodeOl && attrs[Attribute.list.key] != Attribute.ol || attrs.isEmpty) { + if (prevNodeOl && attrs[Attribute.list.key] != Attribute.ol || + attrs.isEmpty) { clearIndents = true; } @@ -561,13 +599,15 @@ class QuillRawEditorState extends EditorState final nodeTextDirection = getDirectionOfNode(node, _textDirection); if (node is Line) { final editableTextLine = _getEditableTextLineFromNode(node, context); - result.add(Directionality(textDirection: nodeTextDirection, child: editableTextLine)); + result.add(Directionality( + textDirection: nodeTextDirection, child: editableTextLine)); } else if (node is Block) { final editableTextBlock = EditableTextBlock( block: node, placeholderBuilder: widget.config.placeholderBuilder, controller: controller, - cursorParagrahPlaceholderConfiguration: widget.config.cursorParagrahPlaceholderConfiguration, + cursorParagrahPlaceholderConfiguration: + widget.config.cursorParagrahPlaceholderConfiguration, customLeadingBlockBuilder: widget.config.customLeadingBuilder, textDirection: nodeTextDirection, scrollBottomInset: widget.config.scrollBottomInset, @@ -578,7 +618,9 @@ class QuillRawEditorState extends EditorState styles: _styles, enableInteractiveSelection: widget.config.enableInteractiveSelection, hasFocus: _hasFocus, - contentPadding: attrs.containsKey(Attribute.codeBlock.key) ? const EdgeInsets.all(16) : null, + contentPadding: attrs.containsKey(Attribute.codeBlock.key) + ? const EdgeInsets.all(16) + : null, embedBuilder: widget.config.embedBuilder, linkActionPicker: _linkActionPicker, onLaunchUrl: widget.config.onLaunchUrl, @@ -610,7 +652,8 @@ class QuillRawEditorState extends EditorState return result; } - EditableTextLine _getEditableTextLineFromNode(Line node, BuildContext context) { + EditableTextLine _getEditableTextLineFromNode( + Line node, BuildContext context) { final textLine = TextLine( line: node, textDirection: _textDirection, @@ -711,7 +754,8 @@ class QuillRawEditorState extends EditorState return defaultStyles!.paragraph!.verticalSpacing; } - HorizontalSpacing _getHorizontalSpacingForBlock(Block node, DefaultStyles? defaultStyles) { + HorizontalSpacing _getHorizontalSpacingForBlock( + Block node, DefaultStyles? defaultStyles) { final attrs = node.style.attributes; if (attrs.containsKey(Attribute.blockQuote.key)) { return defaultStyles!.quote!.horizontalSpacing; @@ -727,7 +771,8 @@ class QuillRawEditorState extends EditorState return HorizontalSpacing.zero; } - VerticalSpacing _getVerticalSpacingForBlock(Block node, DefaultStyles? defaultStyles) { + VerticalSpacing _getVerticalSpacingForBlock( + Block node, DefaultStyles? defaultStyles) { final attrs = node.style.attributes; if (attrs.containsKey(Attribute.blockQuote.key)) { return defaultStyles!.quote!.verticalSpacing; @@ -790,7 +835,8 @@ class QuillRawEditorState extends EditorState } else { _keyboardVisibilityController = KeyboardVisibilityController(); _keyboardVisible = _keyboardVisibilityController!.isVisible; - _keyboardVisibilitySubscription = _keyboardVisibilityController?.onChange.listen((visible) { + _keyboardVisibilitySubscription = + _keyboardVisibilityController?.onChange.listen((visible) { _keyboardVisible = visible; if (visible) { _onChangeTextEditingValue(!_hasFocus); @@ -832,7 +878,9 @@ class QuillRawEditorState extends EditorState super.didChangeDependencies(); final parentStyles = QuillStyles.getStyles(context, true); final defaultStyles = DefaultStyles.getInstance(context); - _styles = (parentStyles != null) ? defaultStyles.merge(parentStyles) : defaultStyles; + _styles = (parentStyles != null) + ? defaultStyles.merge(parentStyles) + : defaultStyles; if (widget.config.customStyles != null) { _styles = _styles!.merge(widget.config.customStyles!); @@ -895,7 +943,8 @@ class QuillRawEditorState extends EditorState } bool _shouldShowSelectionHandles() { - return widget.config.showSelectionHandles && !controller.selection.isCollapsed; + return widget.config.showSelectionHandles && + !controller.selection.isCollapsed; } @override @@ -961,7 +1010,8 @@ class QuillRawEditorState extends EditorState } } - _shortcutActionsManager.adjacentLineAction.stopCurrentVerticalRunIfSelectionChanges(); + _shortcutActionsManager.adjacentLineAction + .stopCurrentVerticalRunIfSelectionChanges(); } void _onChangeTextEditingValue([bool ignoreCaret = false]) { @@ -1027,14 +1077,16 @@ class QuillRawEditorState extends EditorState contextMenuBuilder: widget.config.contextMenuBuilder == null ? null : (context) => widget.config.contextMenuBuilder!(context, this), - magnifierConfiguration: widget.config.magnifierConfiguration ?? TextMagnifier.adaptiveMagnifierConfiguration, + magnifierConfiguration: widget.config.magnifierConfiguration ?? + TextMagnifier.adaptiveMagnifierConfiguration, ); } void _handleFocusChanged() { if (dirty) { requestKeyboard(); - SchedulerBinding.instance.addPostFrameCallback((_) => _handleFocusChanged()); + SchedulerBinding.instance + .addPostFrameCallback((_) => _handleFocusChanged()); return; } openOrCloseConnection(); @@ -1085,7 +1137,8 @@ class QuillRawEditorState extends EditorState } final viewport = RenderAbstractViewport.of(renderEditor); - final editorOffset = renderEditor.localToGlobal(const Offset(0, 0), ancestor: viewport); + final editorOffset = + renderEditor.localToGlobal(const Offset(0, 0), ancestor: viewport); final offsetInViewport = _scrollController.offset + editorOffset.dy; final offset = renderEditor.getOffsetToRevealCursor( @@ -1113,7 +1166,8 @@ class QuillRawEditorState extends EditorState /// /// This property is typically used to notify the renderer of input gestures. @override - RenderEditor get renderEditor => _editorKey.currentContext!.findRenderObject() as RenderEditor; + RenderEditor get renderEditor => + _editorKey.currentContext!.findRenderObject() as RenderEditor; /// Express interest in interacting with the keyboard. /// @@ -1189,7 +1243,8 @@ class QuillRawEditorState extends EditorState bool get wantKeepAlive => widget.config.focusNode.hasFocus; @override - AnimationController get floatingCursorResetController => _floatingCursorResetController; + AnimationController get floatingCursorResetController => + _floatingCursorResetController; late AnimationController _floatingCursorResetController; @@ -1257,7 +1312,8 @@ class QuillRawEditorState extends EditorState if (_selectionOverlay == null) return; final position = renderEditor.getPositionForOffset(positionToShow); if (_selectionOverlay!.isMagnifierVisible) { - _selectionOverlay!.updateMagnifier(position, positionToShow, renderEditor); + _selectionOverlay! + .updateMagnifier(position, positionToShow, renderEditor); } else { _selectionOverlay!.showMagnifier(position, positionToShow, renderEditor); } From 3a37acd7a8b047269f157c796f600a45c10e5721 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 02:29:32 -0400 Subject: [PATCH 096/113] Chore: rename class names to make more sense with their functions --- lib/src/editor/config/editor_config.dart | 10 +++--- .../placeholder_builder_internal.dart | 17 ++-------- .../placeholder_configuration.dart | 25 +++++++-------- .../raw_editor/config/raw_editor_config.dart | 3 +- lib/src/editor/widgets/cursor.dart | 1 - .../cursor_configuration.dart | 32 +++++++++++-------- lib/src/editor/widgets/text/text_block.dart | 1 - 7 files changed, 39 insertions(+), 50 deletions(-) diff --git a/lib/src/editor/config/editor_config.dart b/lib/src/editor/config/editor_config.dart index 309a16e22..d2f16699f 100644 --- a/lib/src/editor/config/editor_config.dart +++ b/lib/src/editor/config/editor_config.dart @@ -169,11 +169,10 @@ class QuillEditorConfig { /// customBlockAttributesKeys: null, ///), ///``` - final PlaceholderComponentsConfiguration? placeholderComponentsConfiguration; + final PlaceholderConfig? placeholderComponentsConfiguration; /// This argument configure how will be showed the placeholder at right or left of the cursor - final CursorParagrahPlaceholderConfiguration? - cursorParagrahPlaceholderConfiguration; + final CursorPlaceholderConfig? cursorParagrahPlaceholderConfiguration; /// A handler for keys that are pressed when the editor is focused. /// @@ -543,10 +542,9 @@ class QuillEditorConfig { ContentInsertionConfiguration? contentInsertionConfiguration, GlobalKey? editorKey, TextSelectionThemeData? textSelectionThemeData, - PlaceholderComponentsConfiguration? placeholderComponentsConfiguration, + PlaceholderConfig? placeholderComponentsConfiguration, bool? requestKeyboardFocusOnCheckListChanged, - CursorParagrahPlaceholderConfiguration? - cursorParagrahPlaceholderConfiguration, + CursorPlaceholderConfig? cursorParagrahPlaceholderConfiguration, TextMagnifierConfiguration? magnifierConfiguration, TextInputAction? textInputAction, bool? enableScribble, diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 2fe93eae3..204baf6d0 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -1,16 +1,5 @@ // This file is only for internal use -import 'package:flutter/material.dart' - show - Expanded, - Row, - StrutStyle, - Text, - TextAlign, - TextDirection, - TextStyle, - TextWidthBasis, - WidgetSpan, - immutable; +import 'package:flutter/material.dart'; import 'package:meta/meta.dart'; import '../../../../document/attribute.dart' show Attribute, AttributeScope; import '../../../../document/nodes/line.dart'; @@ -36,9 +25,9 @@ class PlaceholderBuilder { required this.configuration, }); - final PlaceholderComponentsConfiguration configuration; + final PlaceholderConfig configuration; - Map get builders => + Map get builders => configuration.builders; Set? get customBlockAttributesKeys => configuration.customBlockAttributesKeys; diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart index 5a0f1c77a..a2e307727 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart @@ -1,30 +1,30 @@ import 'package:flutter/material.dart' show TextStyle, immutable; import '../../../../document/attribute.dart'; -typedef PlaceholderConfigurationBuilder = PlaceholderArguments? Function( +typedef PlaceholderComponentBuilder = PlaceholderTextBuilder? Function( Attribute, TextStyle); @immutable -class PlaceholderComponentsConfiguration { - const PlaceholderComponentsConfiguration({ +class PlaceholderConfig { + const PlaceholderConfig({ required this.builders, this.customBlockAttributesKeys, }); - factory PlaceholderComponentsConfiguration.base() { - return const PlaceholderComponentsConfiguration(builders: {}); + factory PlaceholderConfig.base() { + return const PlaceholderConfig(builders: {}); } /// These attributes are used with the default ones /// to let us add placeholder to custom block attributes final Set? customBlockAttributesKeys; - final Map builders; + final Map builders; - PlaceholderComponentsConfiguration copyWith({ - Map? builders, + PlaceholderConfig copyWith({ + Map? builders, Set? customBlockAttributesKeys, }) { - return PlaceholderComponentsConfiguration( + return PlaceholderConfig( builders: builders ?? this.builders, customBlockAttributesKeys: customBlockAttributesKeys ?? this.customBlockAttributesKeys, @@ -34,10 +34,9 @@ class PlaceholderComponentsConfiguration { @immutable -/// Represents the arguments that builds the text that will -/// be displayed -class PlaceholderArguments { - const PlaceholderArguments({ +/// Represents the text that will be displayed +class PlaceholderTextBuilder { + const PlaceholderTextBuilder({ required this.placeholderText, required this.style, }); diff --git a/lib/src/editor/raw_editor/config/raw_editor_config.dart b/lib/src/editor/raw_editor/config/raw_editor_config.dart index e749b52a3..ece64f9b9 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_config.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_config.dart @@ -135,8 +135,7 @@ class QuillRawEditorConfig { final List spaceShortcutEvents; /// This argument configure how will be showed the placeholder at right or left of the cursor - final CursorParagrahPlaceholderConfiguration? - cursorParagrahPlaceholderConfiguration; + final CursorPlaceholderConfig? cursorParagrahPlaceholderConfiguration; /// A handler for keys that are pressed when the editor is focused. /// diff --git a/lib/src/editor/widgets/cursor.dart b/lib/src/editor/widgets/cursor.dart index 8152bf75b..0cd095071 100644 --- a/lib/src/editor/widgets/cursor.dart +++ b/lib/src/editor/widgets/cursor.dart @@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart'; import '../../common/utils/platform.dart'; import '../../document/nodes/line.dart'; import 'box.dart'; -import 'cursor_configuration/cursor_configuration.dart'; /// Style properties of editing cursor. class CursorStyle { diff --git a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart index 5d89863fb..754fa181d 100644 --- a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart +++ b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart @@ -1,6 +1,8 @@ -import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; +const TextStyle _defaultPlaceholderStyle = + TextStyle(color: Colors.grey, fontStyle: FontStyle.italic); + /// This class contains all necessary configurations /// to show the wanted placeholder at the level of the cursor /// @@ -8,29 +10,24 @@ import 'package:flutter/material.dart'; /// where if the line is empty and not contains any block style (like /// header, align, codeblock, etc), then will show a text /// like (assume that "|" is the cursor): "| start writing" - -const TextStyle _defaultPlaceholderStyle = - TextStyle(color: Colors.grey, fontStyle: FontStyle.italic); - @immutable -class CursorParagrahPlaceholderConfiguration extends Equatable { - const CursorParagrahPlaceholderConfiguration({ +class CursorPlaceholderConfig { + const CursorPlaceholderConfig({ required this.paragraphPlaceholderText, required this.style, required this.show, }); - factory CursorParagrahPlaceholderConfiguration.withPlaceholder( - {TextStyle? style}) { - return CursorParagrahPlaceholderConfiguration( + factory CursorPlaceholderConfig.basic({TextStyle? style}) { + return CursorPlaceholderConfig( paragraphPlaceholderText: 'Enter text...', style: style ?? _defaultPlaceholderStyle, show: true, ); } - factory CursorParagrahPlaceholderConfiguration.noPlaceholder() { - return const CursorParagrahPlaceholderConfiguration( + factory CursorPlaceholderConfig.noPlaceholder() { + return const CursorPlaceholderConfig( paragraphPlaceholderText: '', style: TextStyle(), show: false, @@ -48,5 +45,14 @@ class CursorParagrahPlaceholderConfiguration extends Equatable { final bool show; @override - List get props => [paragraphPlaceholderText, style, show]; + int get hashCode => + paragraphPlaceholderText.hashCode ^ style.hashCode ^ show.hashCode; + + @override + bool operator ==(covariant CursorPlaceholderConfig other) { + if (identical(this, other)) return true; + return other.show == show && + other.paragraphPlaceholderText == paragraphPlaceholderText && + other.style == style; + } } diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index 8c50258f2..51bdf1361 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -16,7 +16,6 @@ import '../../raw_editor/builders/leading_block_builder.dart'; import '../../raw_editor/builders/placeholder/placeholder_builder_internal.dart'; import '../box.dart'; import '../cursor.dart'; -import '../cursor_configuration/cursor_configuration.dart'; import '../default_leading_components/leading_components.dart'; import '../default_styles.dart'; import '../delegate.dart'; From 33a8cdd1a02cebbbecc5d53c115a4dddbb1bf09b Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 02:34:04 -0400 Subject: [PATCH 097/113] Chore: fix missed changes on cursor, text_block and text_line --- lib/src/editor/widgets/cursor.dart | 3 ++- lib/src/editor/widgets/text/text_block.dart | 9 ++++---- lib/src/editor/widgets/text/text_line.dart | 24 ++++++++++----------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/src/editor/widgets/cursor.dart b/lib/src/editor/widgets/cursor.dart index 0cd095071..d6d0c7007 100644 --- a/lib/src/editor/widgets/cursor.dart +++ b/lib/src/editor/widgets/cursor.dart @@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart'; import '../../common/utils/platform.dart'; import '../../document/nodes/line.dart'; import 'box.dart'; +import 'cursor_configuration/cursor_configuration.dart'; /// Style properties of editing cursor. class CursorStyle { @@ -264,7 +265,7 @@ class CursorPainter { TextPosition position, bool lineHasEmbed, Line node, - CursorParagrahPlaceholderConfiguration? cursorPlaceholderConfiguration, + CursorPlaceholderConfig? cursorPlaceholderConfiguration, TextDirection textDirection, ) { // relative (x, y) to global offset diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index 51bdf1361..0e45ae6b6 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -16,6 +16,7 @@ import '../../raw_editor/builders/leading_block_builder.dart'; import '../../raw_editor/builders/placeholder/placeholder_builder_internal.dart'; import '../box.dart'; import '../cursor.dart'; +import '../cursor_configuration/cursor_configuration.dart'; import '../default_leading_components/leading_components.dart'; import '../default_styles.dart'; import '../delegate.dart'; @@ -79,7 +80,7 @@ class EditableTextBlock extends StatelessWidget { required this.readOnly, required this.customRecognizerBuilder, required this.placeholderBuilder, - required this.cursorParagrahPlaceholderConfiguration, + required this.cursorPlaceholderConfig, required this.composingRange, this.checkBoxReadOnly, this.onLaunchUrl, @@ -96,8 +97,8 @@ class EditableTextBlock extends StatelessWidget { final HorizontalSpacing horizontalSpacing; final VerticalSpacing verticalSpacing; final PlaceholderBuilder? placeholderBuilder; - final CursorParagrahPlaceholderConfiguration? - cursorParagrahPlaceholderConfiguration; + final CursorPlaceholderConfig? + cursorPlaceholderConfig; final TextSelection textSelection; final Color color; final DefaultStyles? styles; @@ -213,7 +214,7 @@ class EditableTextBlock extends StatelessWidget { MediaQuery.devicePixelRatioOf(context), cursorCont, styles!.inlineCode!, - cursorParagrahPlaceholderConfiguration, + cursorPlaceholderConfig, ); final nodeTextDirection = getDirectionOfNode(line, textDirection); children.add( diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 0d7b9ec4e..8fd7fda7d 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -714,7 +714,7 @@ class EditableTextLine extends RenderObjectWidget { this.devicePixelRatio, this.cursorCont, this.inlineCodeStyle, - this.cursorParagrahPlaceholderConfiguration, + this.cursorPlaceholderConfig, {super.key}); final Line line; @@ -722,8 +722,8 @@ class EditableTextLine extends RenderObjectWidget { final Widget body; final HorizontalSpacing horizontalSpacing; final VerticalSpacing verticalSpacing; - final CursorParagrahPlaceholderConfiguration? - cursorParagrahPlaceholderConfiguration; + final CursorPlaceholderConfig? + cursorPlaceholderConfig; final TextDirection textDirection; final TextSelection textSelection; final Color color; @@ -751,7 +751,7 @@ class EditableTextLine extends RenderObjectWidget { color, cursorCont, inlineCodeStyle, - cursorParagrahPlaceholderConfiguration, + cursorPlaceholderConfig, ); } @@ -765,7 +765,7 @@ class EditableTextLine extends RenderObjectWidget { ..setTextSelection(textSelection) ..setColor(color) ..setCursorParagraphPlaceholderConfiguration( - cursorParagrahPlaceholderConfiguration) + cursorPlaceholderConfig) ..setEnableInteractiveSelection(enableInteractiveSelection) ..hasFocus = hasFocus ..setDevicePixelRatio(devicePixelRatio) @@ -797,7 +797,7 @@ class RenderEditableTextLine extends RenderEditableBox { this.color, this.cursorCont, this.inlineCodeStyle, - this.cursorParagrahPlaceholderConfiguration, + this.cursorPlaceholderConfig, ); RenderBox? _leading; @@ -807,8 +807,8 @@ class RenderEditableTextLine extends RenderEditableBox { TextSelection textSelection; Color color; bool enableInteractiveSelection; - CursorParagrahPlaceholderConfiguration? - cursorParagrahPlaceholderConfiguration; + CursorPlaceholderConfig? + cursorPlaceholderConfig; bool hasFocus = false; double devicePixelRatio; EdgeInsetsGeometry padding; @@ -838,11 +838,11 @@ class RenderEditableTextLine extends RenderEditableBox { } void setCursorParagraphPlaceholderConfiguration( - CursorParagrahPlaceholderConfiguration? c) { - if (cursorParagrahPlaceholderConfiguration == c) { + CursorPlaceholderConfig? c) { + if (cursorPlaceholderConfig == c) { return; } - cursorParagrahPlaceholderConfiguration = c; + cursorPlaceholderConfig = c; markNeedsLayout(); } @@ -1453,7 +1453,7 @@ class RenderEditableTextLine extends RenderEditableBox { position, lineHasEmbed, line, - cursorParagrahPlaceholderConfiguration, + cursorPlaceholderConfig, textDirection, ); } From ce4c09bb417de1dac4062b9b630be94e2e7748b7 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 02:37:49 -0400 Subject: [PATCH 098/113] Chore: changed param names to have the same from their classes --- lib/src/editor/config/editor_config.dart | 12 ++++++------ lib/src/editor/editor.dart | 4 ++-- .../editor/raw_editor/config/raw_editor_config.dart | 4 ++-- lib/src/editor/raw_editor/raw_editor_state.dart | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/src/editor/config/editor_config.dart b/lib/src/editor/config/editor_config.dart index d2f16699f..a8a603ab5 100644 --- a/lib/src/editor/config/editor_config.dart +++ b/lib/src/editor/config/editor_config.dart @@ -29,7 +29,7 @@ class QuillEditorConfig { this.scrollable = true, this.padding = EdgeInsets.zero, this.placeholderComponentsConfiguration, - this.cursorParagrahPlaceholderConfiguration, + this.cursorPlaceholderConfig, @experimental this.characterShortcutEvents = const [], @experimental this.spaceShortcutEvents = const [], this.autoFocus = false, @@ -172,7 +172,7 @@ class QuillEditorConfig { final PlaceholderConfig? placeholderComponentsConfiguration; /// This argument configure how will be showed the placeholder at right or left of the cursor - final CursorPlaceholderConfig? cursorParagrahPlaceholderConfiguration; + final CursorPlaceholderConfig? cursorPlaceholderConfig; /// A handler for keys that are pressed when the editor is focused. /// @@ -544,7 +544,7 @@ class QuillEditorConfig { TextSelectionThemeData? textSelectionThemeData, PlaceholderConfig? placeholderComponentsConfiguration, bool? requestKeyboardFocusOnCheckListChanged, - CursorPlaceholderConfig? cursorParagrahPlaceholderConfiguration, + CursorPlaceholderConfig? cursorPlaceholderConfig, TextMagnifierConfiguration? magnifierConfiguration, TextInputAction? textInputAction, bool? enableScribble, @@ -553,9 +553,9 @@ class QuillEditorConfig { void Function(TextInputAction action)? onPerformAction, }) { return QuillEditorConfig( - cursorParagrahPlaceholderConfiguration: - cursorParagrahPlaceholderConfiguration ?? - this.cursorParagrahPlaceholderConfiguration, + cursorPlaceholderConfig: + cursorPlaceholderConfig ?? + this.cursorPlaceholderConfig, placeholderComponentsConfiguration: placeholderComponentsConfiguration ?? this.placeholderComponentsConfiguration, customLeadingBlockBuilder: diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index b42977915..7eec27e50 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -267,8 +267,8 @@ class QuillEditorState extends State config: QuillRawEditorConfig( characterShortcutEvents: widget.config.characterShortcutEvents, spaceShortcutEvents: widget.config.spaceShortcutEvents, - cursorParagrahPlaceholderConfiguration: - widget.config.cursorParagrahPlaceholderConfiguration, + cursorPlaceholderConfig: + widget.config.cursorPlaceholderConfig, placeholderBuilder: placeholderBuilder, onKeyPressed: widget.config.onKeyPressed, customLeadingBuilder: widget.config.customLeadingBlockBuilder, diff --git a/lib/src/editor/raw_editor/config/raw_editor_config.dart b/lib/src/editor/raw_editor/config/raw_editor_config.dart index ece64f9b9..20e489021 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_config.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_config.dart @@ -31,7 +31,7 @@ class QuillRawEditorConfig { required this.characterShortcutEvents, required this.spaceShortcutEvents, this.placeholderBuilder, - this.cursorParagrahPlaceholderConfiguration, + this.cursorPlaceholderConfig, @experimental this.onKeyPressed, this.showCursor = true, this.scrollable = true, @@ -135,7 +135,7 @@ class QuillRawEditorConfig { final List spaceShortcutEvents; /// This argument configure how will be showed the placeholder at right or left of the cursor - final CursorPlaceholderConfig? cursorParagrahPlaceholderConfiguration; + final CursorPlaceholderConfig? cursorPlaceholderConfig; /// A handler for keys that are pressed when the editor is focused. /// diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 6cbe27fd3..689a89e7e 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -606,8 +606,8 @@ class QuillRawEditorState extends EditorState block: node, placeholderBuilder: widget.config.placeholderBuilder, controller: controller, - cursorParagrahPlaceholderConfiguration: - widget.config.cursorParagrahPlaceholderConfiguration, + cursorPlaceholderConfig: + widget.config.cursorPlaceholderConfig, customLeadingBlockBuilder: widget.config.customLeadingBuilder, textDirection: nodeTextDirection, scrollBottomInset: widget.config.scrollBottomInset, @@ -683,7 +683,7 @@ class QuillRawEditorState extends EditorState MediaQuery.devicePixelRatioOf(context), _cursorCont, _styles!.inlineCode!, - widget.config.cursorParagrahPlaceholderConfiguration, + widget.config.cursorPlaceholderConfig, ); return editableTextLine; } From 47bfd2b67bddd959d741c00bed3bdb09c2ab12e8 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 10:41:41 -0400 Subject: [PATCH 099/113] Chore: fixed placeholders text scale issue on mobile devices --- example/lib/main.dart | 47 ++++++++++++++----- .../placeholder_builder_internal.dart | 4 ++ lib/src/editor/widgets/cursor.dart | 16 ++++--- .../cursor_configuration.dart | 32 ++++++++----- lib/src/editor/widgets/text/text_line.dart | 1 + 5 files changed, 68 insertions(+), 32 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index ac53434bd..b8cb89dc8 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -52,8 +52,7 @@ class _HomePageState extends State { } // Save the image somewhere and return the image URL that will be // stored in the Quill Delta JSON (the document). - final newFileName = - 'image-file-${DateTime.now().toIso8601String()}.png'; + final newFileName = 'image-file-${DateTime.now().toIso8601String()}.png'; final newPath = path.join( io.Directory.systemTemp.path, newFileName, @@ -86,9 +85,8 @@ class _HomePageState extends State { icon: const Icon(Icons.output), tooltip: 'Print Delta JSON to log', onPressed: () { - ScaffoldMessenger.of(context).showSnackBar(const SnackBar( - content: - Text('The JSON Delta has been printed to the console.'))); + ScaffoldMessenger.of(context) + .showSnackBar(const SnackBar(content: Text('The JSON Delta has been printed to the console.'))); debugPrint(jsonEncode(_controller.document.toDelta().toJson())); }, ), @@ -127,11 +125,8 @@ class _HomePageState extends State { buttonOptions: QuillSimpleToolbarButtonOptions( base: QuillToolbarBaseButtonOptions( afterButtonPressed: () { - final isDesktop = { - TargetPlatform.linux, - TargetPlatform.windows, - TargetPlatform.macOS - }.contains(defaultTargetPlatform); + final isDesktop = {TargetPlatform.linux, TargetPlatform.windows, TargetPlatform.macOS} + .contains(defaultTargetPlatform); if (isDesktop) { _editorFocusNode.requestFocus(); } @@ -147,6 +142,35 @@ class _HomePageState extends State { controller: _controller, config: QuillEditorConfig( placeholder: 'Start writing your notes...', + characterShortcutEvents: standardCharactersShortcutEvents, + spaceShortcutEvents: standardSpaceShorcutEvents, + cursorPlaceholderConfig: CursorPlaceholderConfig( + text: 'Write something...', + textStyle: TextStyle(color: Colors.grey, fontStyle: FontStyle.italic), + show: true, + offset: Offset(3.5, 2) + ), + placeholderComponentsConfiguration: PlaceholderConfig( + builders: { + Attribute.header.key: (Attribute attr, style) { + final values = [30, 27, 22]; + final level = attr.value as int?; + if (level == null) return null; + final fontSize = values[(level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; + return PlaceholderTextBuilder( + placeholderText: 'Header $level', + style: + TextStyle(fontSize: fontSize.toDouble()).merge(style.copyWith(color: Colors.grey)), + ); + }, + Attribute.list.key: (Attribute attr, style) { + return PlaceholderTextBuilder( + placeholderText: 'List item', + style: style.copyWith(color: Colors.grey), + ); + }, + }, + ), padding: const EdgeInsets.all(16), embedBuilders: [ ...FlutterQuillEmbeds.editorBuilders( @@ -193,8 +217,7 @@ class TimeStampEmbed extends Embeddable { static const String timeStampType = 'timeStamp'; - static TimeStampEmbed fromDocument(Document document) => - TimeStampEmbed(jsonEncode(document.toDelta().toJson())); + static TimeStampEmbed fromDocument(Document document) => TimeStampEmbed(jsonEncode(document.toDelta().toJson())); Document get document => Document.fromJson(jsonDecode(data)); } diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 204baf6d0..92fd44df7 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -70,6 +70,7 @@ class PlaceholderBuilder { required TextAlign align, TextDirection? textDirection, StrutStyle? strutStyle, + TextScaler? textScaler, }) { if (builders.isEmpty) return null; final configuration = @@ -78,6 +79,8 @@ class PlaceholderBuilder { if (configuration == null || configuration.placeholderText.trim().isEmpty) { return null; } + //TODO: solo en telefonos, este codigo es erroneo. Por qué? Ni idea. + // Podria ser tema nativo, pero solucionemoslo como podamos final textWidget = Text( configuration.placeholderText, style: configuration.style, @@ -85,6 +88,7 @@ class PlaceholderBuilder { softWrap: true, strutStyle: strutStyle, textAlign: align, + textScaler: textScaler, textWidthBasis: TextWidthBasis.longestLine, ); // we use [Row] widget with [Expanded] to take whole the available width diff --git a/lib/src/editor/widgets/cursor.dart b/lib/src/editor/widgets/cursor.dart index d6d0c7007..b864ac6b4 100644 --- a/lib/src/editor/widgets/cursor.dart +++ b/lib/src/editor/widgets/cursor.dart @@ -265,7 +265,7 @@ class CursorPainter { TextPosition position, bool lineHasEmbed, Line node, - CursorPlaceholderConfig? cursorPlaceholderConfiguration, + CursorPlaceholderConfig? cursorPlaceholderConfig, TextDirection textDirection, ) { // relative (x, y) to global offset @@ -332,22 +332,24 @@ class CursorPainter { canvas.drawRRect(caretRRect, paint); } // we need to make these checks to avoid use this painter unnecessarily - if (cursorPlaceholderConfiguration != null && - cursorPlaceholderConfiguration.show && - cursorPlaceholderConfiguration.paragraphPlaceholderText + if (cursorPlaceholderConfig != null && + cursorPlaceholderConfig.show && + cursorPlaceholderConfig.text .trim() .isNotEmpty) { if (_isNodeInline(node) && node.isEmpty) { + final localOffset = cursorPlaceholderConfig.offset; + if(localOffset == null) return; placeholderPainter ??= TextPainter( text: TextSpan( - text: cursorPlaceholderConfiguration.paragraphPlaceholderText, - style: cursorPlaceholderConfiguration.style, + text: cursorPlaceholderConfig.text, + style: cursorPlaceholderConfig.textStyle, ), textDirection: textDirection, ); placeholderPainter! ..layout() - ..paint(canvas, offset + Offset(3.5, (style.height ?? 2) / 2)); + ..paint(canvas, offset + localOffset); } } } diff --git a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart index 754fa181d..2c19a9050 100644 --- a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart +++ b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart @@ -13,46 +13,52 @@ const TextStyle _defaultPlaceholderStyle = @immutable class CursorPlaceholderConfig { const CursorPlaceholderConfig({ - required this.paragraphPlaceholderText, - required this.style, + required this.text, + required this.textStyle, required this.show, + required this.offset, }); - factory CursorPlaceholderConfig.basic({TextStyle? style}) { + factory CursorPlaceholderConfig.basic({TextStyle? textStyle}) { return CursorPlaceholderConfig( - paragraphPlaceholderText: 'Enter text...', - style: style ?? _defaultPlaceholderStyle, + text: 'Enter text...', + textStyle: textStyle ?? _defaultPlaceholderStyle, show: true, + offset: const Offset(3.5, 5), ); } factory CursorPlaceholderConfig.noPlaceholder() { return const CursorPlaceholderConfig( - paragraphPlaceholderText: '', - style: TextStyle(), + text: '', + textStyle: TextStyle(), show: false, + offset: null, ); } /// The text that will be showed at the right /// or left of the cursor - final String paragraphPlaceholderText; + final String text; - /// The style of the placeholder - final TextStyle style; + /// The textStyle of the placeholder + final TextStyle textStyle; /// Decides if the placeholder should be showed final bool show; + /// Decides the offset where will be painted the text + final Offset? offset; + @override int get hashCode => - paragraphPlaceholderText.hashCode ^ style.hashCode ^ show.hashCode; + text.hashCode ^ textStyle.hashCode ^ show.hashCode ^ offset.hashCode; @override bool operator ==(covariant CursorPlaceholderConfig other) { if (identical(this, other)) return true; return other.show == show && - other.paragraphPlaceholderText == paragraphPlaceholderText && - other.style == style; + other.text == text && + other.textStyle == textStyle && other.offset == offset; } } diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 8fd7fda7d..6b5786614 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -285,6 +285,7 @@ class _TextLineState extends State { lineStyle: style, textDirection: widget.textDirection, align: _getTextAlign(), + textScaler: MediaQuery.textScalerOf(context), strutStyle: StrutStyle.fromTextStyle(style), ); if (placeholderWidget != null) { From 172a85cf10eed6fc3321c0c89ccc0705d5a86dab Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 19:02:13 -0400 Subject: [PATCH 100/113] Chore: dart formatting --- lib/src/editor/config/editor_config.dart | 3 +-- lib/src/editor/editor.dart | 3 +-- .../placeholder/placeholder_builder_internal.dart | 2 -- lib/src/editor/raw_editor/raw_editor_state.dart | 3 +-- lib/src/editor/widgets/cursor.dart | 6 ++---- .../cursor_configuration/cursor_configuration.dart | 5 +++-- lib/src/editor/widgets/text/text_block.dart | 3 +-- lib/src/editor/widgets/text/text_line.dart | 12 ++++-------- 8 files changed, 13 insertions(+), 24 deletions(-) diff --git a/lib/src/editor/config/editor_config.dart b/lib/src/editor/config/editor_config.dart index a8a603ab5..b941f51e8 100644 --- a/lib/src/editor/config/editor_config.dart +++ b/lib/src/editor/config/editor_config.dart @@ -554,8 +554,7 @@ class QuillEditorConfig { }) { return QuillEditorConfig( cursorPlaceholderConfig: - cursorPlaceholderConfig ?? - this.cursorPlaceholderConfig, + cursorPlaceholderConfig ?? this.cursorPlaceholderConfig, placeholderComponentsConfiguration: placeholderComponentsConfiguration ?? this.placeholderComponentsConfiguration, customLeadingBlockBuilder: diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 7eec27e50..cf4d21303 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -267,8 +267,7 @@ class QuillEditorState extends State config: QuillRawEditorConfig( characterShortcutEvents: widget.config.characterShortcutEvents, spaceShortcutEvents: widget.config.spaceShortcutEvents, - cursorPlaceholderConfig: - widget.config.cursorPlaceholderConfig, + cursorPlaceholderConfig: widget.config.cursorPlaceholderConfig, placeholderBuilder: placeholderBuilder, onKeyPressed: widget.config.onKeyPressed, customLeadingBuilder: widget.config.customLeadingBlockBuilder, diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart index 92fd44df7..a31bc602e 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart @@ -79,8 +79,6 @@ class PlaceholderBuilder { if (configuration == null || configuration.placeholderText.trim().isEmpty) { return null; } - //TODO: solo en telefonos, este codigo es erroneo. Por qué? Ni idea. - // Podria ser tema nativo, pero solucionemoslo como podamos final textWidget = Text( configuration.placeholderText, style: configuration.style, diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index 689a89e7e..343e68cd8 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -606,8 +606,7 @@ class QuillRawEditorState extends EditorState block: node, placeholderBuilder: widget.config.placeholderBuilder, controller: controller, - cursorPlaceholderConfig: - widget.config.cursorPlaceholderConfig, + cursorPlaceholderConfig: widget.config.cursorPlaceholderConfig, customLeadingBlockBuilder: widget.config.customLeadingBuilder, textDirection: nodeTextDirection, scrollBottomInset: widget.config.scrollBottomInset, diff --git a/lib/src/editor/widgets/cursor.dart b/lib/src/editor/widgets/cursor.dart index b864ac6b4..7cc2644bc 100644 --- a/lib/src/editor/widgets/cursor.dart +++ b/lib/src/editor/widgets/cursor.dart @@ -334,12 +334,10 @@ class CursorPainter { // we need to make these checks to avoid use this painter unnecessarily if (cursorPlaceholderConfig != null && cursorPlaceholderConfig.show && - cursorPlaceholderConfig.text - .trim() - .isNotEmpty) { + cursorPlaceholderConfig.text.trim().isNotEmpty) { if (_isNodeInline(node) && node.isEmpty) { final localOffset = cursorPlaceholderConfig.offset; - if(localOffset == null) return; + if (localOffset == null) return; placeholderPainter ??= TextPainter( text: TextSpan( text: cursorPlaceholderConfig.text, diff --git a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart index 2c19a9050..1fbc669a4 100644 --- a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart +++ b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart @@ -47,7 +47,7 @@ class CursorPlaceholderConfig { /// Decides if the placeholder should be showed final bool show; - /// Decides the offset where will be painted the text + /// Decides the offset where will be painted the text final Offset? offset; @override @@ -59,6 +59,7 @@ class CursorPlaceholderConfig { if (identical(this, other)) return true; return other.show == show && other.text == text && - other.textStyle == textStyle && other.offset == offset; + other.textStyle == textStyle && + other.offset == offset; } } diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index 0e45ae6b6..5a92af1d4 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -97,8 +97,7 @@ class EditableTextBlock extends StatelessWidget { final HorizontalSpacing horizontalSpacing; final VerticalSpacing verticalSpacing; final PlaceholderBuilder? placeholderBuilder; - final CursorPlaceholderConfig? - cursorPlaceholderConfig; + final CursorPlaceholderConfig? cursorPlaceholderConfig; final TextSelection textSelection; final Color color; final DefaultStyles? styles; diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 6b5786614..228d1d59e 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -723,8 +723,7 @@ class EditableTextLine extends RenderObjectWidget { final Widget body; final HorizontalSpacing horizontalSpacing; final VerticalSpacing verticalSpacing; - final CursorPlaceholderConfig? - cursorPlaceholderConfig; + final CursorPlaceholderConfig? cursorPlaceholderConfig; final TextDirection textDirection; final TextSelection textSelection; final Color color; @@ -765,8 +764,7 @@ class EditableTextLine extends RenderObjectWidget { ..setTextDirection(textDirection) ..setTextSelection(textSelection) ..setColor(color) - ..setCursorParagraphPlaceholderConfiguration( - cursorPlaceholderConfig) + ..setCursorParagraphPlaceholderConfiguration(cursorPlaceholderConfig) ..setEnableInteractiveSelection(enableInteractiveSelection) ..hasFocus = hasFocus ..setDevicePixelRatio(devicePixelRatio) @@ -808,8 +806,7 @@ class RenderEditableTextLine extends RenderEditableBox { TextSelection textSelection; Color color; bool enableInteractiveSelection; - CursorPlaceholderConfig? - cursorPlaceholderConfig; + CursorPlaceholderConfig? cursorPlaceholderConfig; bool hasFocus = false; double devicePixelRatio; EdgeInsetsGeometry padding; @@ -838,8 +835,7 @@ class RenderEditableTextLine extends RenderEditableBox { markNeedsLayout(); } - void setCursorParagraphPlaceholderConfiguration( - CursorPlaceholderConfig? c) { + void setCursorParagraphPlaceholderConfiguration(CursorPlaceholderConfig? c) { if (cursorPlaceholderConfig == c) { return; } From d022960268c4040d8c852572a444ebdd9a817029 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 19:03:45 -0400 Subject: [PATCH 101/113] Chore: restore example app --- example/lib/main.dart | 47 +++++++++++-------------------------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index b8cb89dc8..ac53434bd 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -52,7 +52,8 @@ class _HomePageState extends State { } // Save the image somewhere and return the image URL that will be // stored in the Quill Delta JSON (the document). - final newFileName = 'image-file-${DateTime.now().toIso8601String()}.png'; + final newFileName = + 'image-file-${DateTime.now().toIso8601String()}.png'; final newPath = path.join( io.Directory.systemTemp.path, newFileName, @@ -85,8 +86,9 @@ class _HomePageState extends State { icon: const Icon(Icons.output), tooltip: 'Print Delta JSON to log', onPressed: () { - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar(content: Text('The JSON Delta has been printed to the console.'))); + ScaffoldMessenger.of(context).showSnackBar(const SnackBar( + content: + Text('The JSON Delta has been printed to the console.'))); debugPrint(jsonEncode(_controller.document.toDelta().toJson())); }, ), @@ -125,8 +127,11 @@ class _HomePageState extends State { buttonOptions: QuillSimpleToolbarButtonOptions( base: QuillToolbarBaseButtonOptions( afterButtonPressed: () { - final isDesktop = {TargetPlatform.linux, TargetPlatform.windows, TargetPlatform.macOS} - .contains(defaultTargetPlatform); + final isDesktop = { + TargetPlatform.linux, + TargetPlatform.windows, + TargetPlatform.macOS + }.contains(defaultTargetPlatform); if (isDesktop) { _editorFocusNode.requestFocus(); } @@ -142,35 +147,6 @@ class _HomePageState extends State { controller: _controller, config: QuillEditorConfig( placeholder: 'Start writing your notes...', - characterShortcutEvents: standardCharactersShortcutEvents, - spaceShortcutEvents: standardSpaceShorcutEvents, - cursorPlaceholderConfig: CursorPlaceholderConfig( - text: 'Write something...', - textStyle: TextStyle(color: Colors.grey, fontStyle: FontStyle.italic), - show: true, - offset: Offset(3.5, 2) - ), - placeholderComponentsConfiguration: PlaceholderConfig( - builders: { - Attribute.header.key: (Attribute attr, style) { - final values = [30, 27, 22]; - final level = attr.value as int?; - if (level == null) return null; - final fontSize = values[(level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; - return PlaceholderTextBuilder( - placeholderText: 'Header $level', - style: - TextStyle(fontSize: fontSize.toDouble()).merge(style.copyWith(color: Colors.grey)), - ); - }, - Attribute.list.key: (Attribute attr, style) { - return PlaceholderTextBuilder( - placeholderText: 'List item', - style: style.copyWith(color: Colors.grey), - ); - }, - }, - ), padding: const EdgeInsets.all(16), embedBuilders: [ ...FlutterQuillEmbeds.editorBuilders( @@ -217,7 +193,8 @@ class TimeStampEmbed extends Embeddable { static const String timeStampType = 'timeStamp'; - static TimeStampEmbed fromDocument(Document document) => TimeStampEmbed(jsonEncode(document.toDelta().toJson())); + static TimeStampEmbed fromDocument(Document document) => + TimeStampEmbed(jsonEncode(document.toDelta().toJson())); Document get document => Document.fromJson(jsonDecode(data)); } From ce51947c58fb36f0fcc9a5c2bbc4419deff1c91d Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 19:12:00 -0400 Subject: [PATCH 102/113] Chore: removed _internal part from placeholder_builder file --- ..._builder_internal.dart => placeholder_builder.dart} | 10 ++++------ .../placeholder/placeholder_configuration.dart | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) rename lib/src/editor/raw_editor/builders/placeholder/{placeholder_builder_internal.dart => placeholder_builder.dart} (96%) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart similarity index 96% rename from lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart rename to lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart index a31bc602e..8a776854a 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder_internal.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart @@ -1,4 +1,6 @@ -// This file is only for internal use +@internal +library; + import 'package:flutter/material.dart'; import 'package:meta/meta.dart'; import '../../../../document/attribute.dart' show Attribute, AttributeScope; @@ -7,8 +9,7 @@ import 'placeholder_configuration.dart'; /// This is the black list of the keys that cannot be /// used or permitted by the builder -// ignore: unnecessary_late -late final List _blackList = List.unmodifiable([ +final List _blackList = List.unmodifiable([ Attribute.align.key, Attribute.direction.key, Attribute.lineHeight.key, @@ -18,7 +19,6 @@ late final List _blackList = List.unmodifiable([ ]); @experimental -@internal @immutable class PlaceholderBuilder { const PlaceholderBuilder({ @@ -34,7 +34,6 @@ class PlaceholderBuilder { /// Check if this node need to show a placeholder @experimental - @internal (bool, String) shouldShowPlaceholder(Line node) { if (builders.isEmpty) return (false, ''); var shouldShow = false; @@ -63,7 +62,6 @@ class PlaceholderBuilder { /// Before use this, we should always use [shouldShowPlaceholder] to avoid /// show any placeholder where is not needed @experimental - @internal WidgetSpan? build({ required Attribute blockAttribute, required TextStyle lineStyle, diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart index a2e307727..5a4cf40c3 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart @@ -32,9 +32,9 @@ class PlaceholderConfig { } } -@immutable /// Represents the text that will be displayed +@immutable class PlaceholderTextBuilder { const PlaceholderTextBuilder({ required this.placeholderText, From 8429efa4a33f65849a1c533aa851e5489e4cc113 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 19:16:00 -0400 Subject: [PATCH 103/113] Chore: improved description of the _blackList in placeholder_builder file --- .../raw_editor/builders/placeholder/placeholder_builder.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart index 8a776854a..fec32b47c 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart @@ -7,8 +7,7 @@ import '../../../../document/attribute.dart' show Attribute, AttributeScope; import '../../../../document/nodes/line.dart'; import 'placeholder_configuration.dart'; -/// This is the black list of the keys that cannot be -/// used or permitted by the builder +// The black list of the keys that can not be used or permitted by the builder. final List _blackList = List.unmodifiable([ Attribute.align.key, Attribute.direction.key, From 6bb3a13f12ee85ea1b2492cffd4f9f09833daf72 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 19:23:06 -0400 Subject: [PATCH 104/113] Chore: convert _isNodeInline into a function in a extension for Node objects --- lib/src/common/extensions/nodes_ext.dart | 10 ++++++++++ lib/src/editor/widgets/cursor.dart | 12 ++---------- lib/src/editor/widgets/text/text_line.dart | 4 +++- 3 files changed, 15 insertions(+), 11 deletions(-) create mode 100644 lib/src/common/extensions/nodes_ext.dart diff --git a/lib/src/common/extensions/nodes_ext.dart b/lib/src/common/extensions/nodes_ext.dart new file mode 100644 index 000000000..a7a18c59b --- /dev/null +++ b/lib/src/common/extensions/nodes_ext.dart @@ -0,0 +1,10 @@ +import '../../document/nodes/node.dart'; + +extension NodesCheckingExtension on Node { + bool isNodeInline(){ + for (final attr in style.attributes.values) { + if (!attr.isInline) return false; + } + return true; + } +} diff --git a/lib/src/editor/widgets/cursor.dart b/lib/src/editor/widgets/cursor.dart index 7cc2644bc..9054ebd9d 100644 --- a/lib/src/editor/widgets/cursor.dart +++ b/lib/src/editor/widgets/cursor.dart @@ -3,7 +3,6 @@ import 'dart:async'; import 'package:flutter/widgets.dart'; import '../../common/utils/platform.dart'; -import '../../document/nodes/line.dart'; import 'box.dart'; import 'cursor_configuration/cursor_configuration.dart'; @@ -264,7 +263,7 @@ class CursorPainter { Offset offset, TextPosition position, bool lineHasEmbed, - Line node, + bool isNodeValid, CursorPlaceholderConfig? cursorPlaceholderConfig, TextDirection textDirection, ) { @@ -335,7 +334,7 @@ class CursorPainter { if (cursorPlaceholderConfig != null && cursorPlaceholderConfig.show && cursorPlaceholderConfig.text.trim().isNotEmpty) { - if (_isNodeInline(node) && node.isEmpty) { + if (isNodeValid) { final localOffset = cursorPlaceholderConfig.offset; if (localOffset == null) return; placeholderPainter ??= TextPainter( @@ -352,13 +351,6 @@ class CursorPainter { } } - bool _isNodeInline(Line node) { - for (final attr in node.style.attributes.values) { - if (!attr.isInline) return false; - } - return true; - } - Offset _getPixelPerfectCursorOffset( Rect caretRect, ) { diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index 228d1d59e..eb31487d3 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -9,6 +9,7 @@ import 'package:flutter/services.dart'; import 'package:url_launcher/url_launcher_string.dart' show launchUrlString; import '../../../../flutter_quill.dart'; +import '../../../common/extensions/nodes_ext.dart'; import '../../../common/utils/color.dart'; import '../../../common/utils/font.dart'; import '../../../common/utils/platform.dart'; @@ -1444,12 +1445,13 @@ class RenderEditableTextLine extends RenderEditableBox { offset: textSelection.extentOffset - line.documentOffset, affinity: textSelection.base.affinity, ); + final isNodeValid = line.isNodeInline() && line.isEmpty; _cursorPainter.paint( context.canvas, effectiveOffset, position, lineHasEmbed, - line, + isNodeValid, cursorPlaceholderConfig, textDirection, ); From 057b8bd91bf0bdcdcbacac01c015b1bb52c88435 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 19:27:25 -0400 Subject: [PATCH 105/113] Chore: dart format and removed unnecessary validation of localOffset for cursorPlaceholderConfig.offset in paint method --- lib/src/common/extensions/nodes_ext.dart | 2 +- .../builders/placeholder/placeholder_configuration.dart | 1 - lib/src/editor/widgets/cursor.dart | 3 +-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/src/common/extensions/nodes_ext.dart b/lib/src/common/extensions/nodes_ext.dart index a7a18c59b..5796735b8 100644 --- a/lib/src/common/extensions/nodes_ext.dart +++ b/lib/src/common/extensions/nodes_ext.dart @@ -1,7 +1,7 @@ import '../../document/nodes/node.dart'; extension NodesCheckingExtension on Node { - bool isNodeInline(){ + bool isNodeInline() { for (final attr in style.attributes.values) { if (!attr.isInline) return false; } diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart index 5a4cf40c3..62ec314dc 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart @@ -32,7 +32,6 @@ class PlaceholderConfig { } } - /// Represents the text that will be displayed @immutable class PlaceholderTextBuilder { diff --git a/lib/src/editor/widgets/cursor.dart b/lib/src/editor/widgets/cursor.dart index 9054ebd9d..ab51fe8c6 100644 --- a/lib/src/editor/widgets/cursor.dart +++ b/lib/src/editor/widgets/cursor.dart @@ -335,8 +335,7 @@ class CursorPainter { cursorPlaceholderConfig.show && cursorPlaceholderConfig.text.trim().isNotEmpty) { if (isNodeValid) { - final localOffset = cursorPlaceholderConfig.offset; - if (localOffset == null) return; + final localOffset = cursorPlaceholderConfig.offset ?? const Offset(0, 0); placeholderPainter ??= TextPainter( text: TextSpan( text: cursorPlaceholderConfig.text, From 47540d4f308fef2e370098d008977160e94da5ca Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 19:38:26 -0400 Subject: [PATCH 106/113] Chore: dart formatting --- lib/src/editor/widgets/cursor.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/editor/widgets/cursor.dart b/lib/src/editor/widgets/cursor.dart index ab51fe8c6..059a6c767 100644 --- a/lib/src/editor/widgets/cursor.dart +++ b/lib/src/editor/widgets/cursor.dart @@ -335,7 +335,8 @@ class CursorPainter { cursorPlaceholderConfig.show && cursorPlaceholderConfig.text.trim().isNotEmpty) { if (isNodeValid) { - final localOffset = cursorPlaceholderConfig.offset ?? const Offset(0, 0); + final localOffset = + cursorPlaceholderConfig.offset ?? const Offset(0, 0); placeholderPainter ??= TextPainter( text: TextSpan( text: cursorPlaceholderConfig.text, From a4177ca7dbcadb0f90c66dbc782810352967d254 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 19:43:23 -0400 Subject: [PATCH 107/113] Fix: import from the old path of placeholder_builder --- lib/src/editor/editor.dart | 2 +- lib/src/editor/raw_editor/config/raw_editor_config.dart | 2 +- lib/src/editor/widgets/text/text_block.dart | 2 +- lib/src/editor/widgets/text/text_line.dart | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index cf4d21303..26ed71116 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -17,7 +17,7 @@ import '../document/nodes/leaf.dart'; import 'config/editor_config.dart'; import 'embed/embed_editor_builder.dart'; import 'magnifier/magnifier_platform_support.dart'; -import 'raw_editor/builders/placeholder/placeholder_builder_internal.dart'; +import 'raw_editor/builders/placeholder/placeholder_builder.dart'; import 'raw_editor/config/raw_editor_config.dart'; import 'raw_editor/raw_editor.dart'; import 'widgets/box.dart'; diff --git a/lib/src/editor/raw_editor/config/raw_editor_config.dart b/lib/src/editor/raw_editor/config/raw_editor_config.dart index 20e489021..0e7d5d8bf 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_config.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_config.dart @@ -14,7 +14,7 @@ import '../../../editor/widgets/link.dart'; import '../../../toolbar/theme/quill_dialog_theme.dart'; import '../../widgets/cursor_configuration/cursor_configuration.dart'; import '../builders/leading_block_builder.dart'; -import '../builders/placeholder/placeholder_builder_internal.dart'; +import '../builders/placeholder/placeholder_builder.dart'; import 'events/events.dart'; @immutable diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index 5a92af1d4..f74e0f826 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -13,7 +13,7 @@ import '../../../editor_toolbar_shared/color.dart'; import '../../editor.dart'; import '../../embed/embed_editor_builder.dart'; import '../../raw_editor/builders/leading_block_builder.dart'; -import '../../raw_editor/builders/placeholder/placeholder_builder_internal.dart'; +import '../../raw_editor/builders/placeholder/placeholder_builder.dart'; import '../box.dart'; import '../cursor.dart'; import '../cursor_configuration/cursor_configuration.dart'; diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index eb31487d3..a2578b7bc 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -15,7 +15,7 @@ import '../../../common/utils/font.dart'; import '../../../common/utils/platform.dart'; import '../../../document/nodes/container.dart' as container_node; import '../../../document/nodes/leaf.dart' as leaf; -import '../../raw_editor/builders/placeholder/placeholder_builder_internal.dart'; +import '../../raw_editor/builders/placeholder/placeholder_builder.dart'; import '../box.dart'; import '../delegate.dart'; import '../keyboard_listener.dart'; From fb5b11a1079ec4579c6b5cfde69f790ea50e4f67 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Thu, 28 Nov 2024 21:25:10 -0400 Subject: [PATCH 108/113] Chore: improved doc comments and renamed params in QuillEditorConfig --- lib/src/editor/config/editor_config.dart | 75 ++++++++++--------- lib/src/editor/editor.dart | 4 +- .../placeholder/placeholder_builder.dart | 46 ++++++------ .../placeholder_configuration.dart | 21 ++++-- .../raw_editor/config/raw_editor_config.dart | 17 +++-- .../cursor_configuration.dart | 22 +++--- 6 files changed, 105 insertions(+), 80 deletions(-) diff --git a/lib/src/editor/config/editor_config.dart b/lib/src/editor/config/editor_config.dart index b941f51e8..4776370ad 100644 --- a/lib/src/editor/config/editor_config.dart +++ b/lib/src/editor/config/editor_config.dart @@ -28,8 +28,8 @@ class QuillEditorConfig { const QuillEditorConfig({ this.scrollable = true, this.padding = EdgeInsets.zero, - this.placeholderComponentsConfiguration, - this.cursorPlaceholderConfig, + @experimental this.placeholderConfig, + @experimental this.cursorPlaceholderConfig, @experimental this.characterShortcutEvents = const [], @experimental this.spaceShortcutEvents = const [], this.autoFocus = false, @@ -141,38 +141,39 @@ class QuillEditorConfig { @experimental final List spaceShortcutEvents; - /// Whether the line is empty, this let us add a placeholder - /// - /// _Note: these placeholders are limited only to lines with block styles_ - /// - /// ### Example - /// - /// Assume that you want to show only a placeholder text for the header items, - /// so, we only need to configure `placeholderComponentsConfiguration` like: - /// - ///```dart - ///final configuration = PlaceholderComponentsConfiguration( - /// builders: { - /// Attribute.header.key: (Attribute attr, style) { - /// final values = [30, 27, 22]; - /// final level = attr.value as int?; - /// if (level == null) return null; - /// final fontSize = values[level - 1]; - /// return PlaceholderArguments( - /// placeholderText: 'Header $level', - /// style: TextStyle(fontSize: fontSize.toDouble()).merge(style), - /// ); - /// }, - /// }, - /// // if you use custom attribute keys into the `builders` param, them you will need to implement that - /// // here too - /// customBlockAttributesKeys: null, - ///), - ///``` - final PlaceholderConfig? placeholderComponentsConfiguration; - - /// This argument configure how will be showed the placeholder at right or left of the cursor - final CursorPlaceholderConfig? cursorPlaceholderConfig; +/// Configuration for displaying placeholders in empty lines or near the cursor. +/// +/// ### Example +/// +/// To show a placeholder text specifically for header items: +/// +/// ```dart +/// final configuration = PlaceholderConfig( +/// builders: { +/// Attribute.header.key: (Attribute attr, style) { +/// final values = [30, 27, 22]; +/// final level = attr.value as int?; +/// if (level == null) return null; +/// final fontSize = values[(level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; +/// return PlaceholderTextBuilder( +/// text: 'Header $level', +/// style: TextStyle(fontSize: fontSize.toDouble()).merge(style), +/// ); +/// }, +/// }, +/// // If using custom attributes, register their keys here. +/// customBlockAttributesKeys: null, +/// ); +/// ``` +@experimental +final PlaceholderConfig? placeholderConfig; + +/// Configures how a placeholder is displayed relative to the cursor. +/// +/// This argument specifies the appearance, style, and position of a placeholder +/// shown at the cursor's location in an empty line. +@experimental +final CursorPlaceholderConfig? cursorPlaceholderConfig; /// A handler for keys that are pressed when the editor is focused. /// @@ -542,7 +543,7 @@ class QuillEditorConfig { ContentInsertionConfiguration? contentInsertionConfiguration, GlobalKey? editorKey, TextSelectionThemeData? textSelectionThemeData, - PlaceholderConfig? placeholderComponentsConfiguration, + PlaceholderConfig? placeholderConfig, bool? requestKeyboardFocusOnCheckListChanged, CursorPlaceholderConfig? cursorPlaceholderConfig, TextMagnifierConfiguration? magnifierConfiguration, @@ -555,8 +556,8 @@ class QuillEditorConfig { return QuillEditorConfig( cursorPlaceholderConfig: cursorPlaceholderConfig ?? this.cursorPlaceholderConfig, - placeholderComponentsConfiguration: placeholderComponentsConfiguration ?? - this.placeholderComponentsConfiguration, + placeholderConfig: placeholderConfig ?? + this.placeholderConfig, customLeadingBlockBuilder: customLeadingBlockBuilder ?? this.customLeadingBlockBuilder, placeholder: placeholder ?? this.placeholder, diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 26ed71116..43ff71863 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -256,11 +256,11 @@ class QuillEditorState extends State final showSelectionToolbar = configurations.enableInteractiveSelection && configurations.enableSelectionToolbar; final placeholderBuilder = - widget.config.placeholderComponentsConfiguration == null + widget.config.placeholderConfig == null ? null : PlaceholderBuilder( configuration: - widget.config.placeholderComponentsConfiguration!); + widget.config.placeholderConfig!); final child = QuillRawEditor( key: _editorKey, controller: controller, diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart index fec32b47c..8ddc45347 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart @@ -17,6 +17,14 @@ final List _blackList = List.unmodifiable([ ...Attribute.ignoreKeys, ]); +/// A utility class for managing placeholder rendering logic in a document editor. +/// +/// The `PlaceholderBuilder` is responsible for determining when a placeholder +/// should be displayed in an empty node and for constructing the corresponding +/// visual representation. +/// +/// - [configuration]: An instance of [PlaceholderConfig] containing placeholder +/// rendering rules and attribute customizations. @experimental @immutable class PlaceholderBuilder { @@ -31,7 +39,14 @@ class PlaceholderBuilder { Set? get customBlockAttributesKeys => configuration.customBlockAttributesKeys; - /// Check if this node need to show a placeholder + /// Determines whether a given [Line] node should display a placeholder. + /// + /// This method checks if the node is empty and contains a block-level attribute + /// matching a builder key or custom attribute, excluding keys in the blacklist. + /// + /// Returns a tuple: + /// - [bool]: Whether a placeholder should be shown. + /// - [String]: The key of the matching attribute, if applicable. @experimental (bool, String) shouldShowPlaceholder(Line node) { if (builders.isEmpty) return (false, ''); @@ -54,12 +69,11 @@ class PlaceholderBuilder { return (node.isEmpty && shouldShow, key); } - /// Build is similar to build method from any widget but - /// this only has the responsability of create a WidgetSpan to be showed - /// by the line when the node is empty + /// Constructs a [WidgetSpan] for rendering a placeholder in an empty line. /// - /// Before use this, we should always use [shouldShowPlaceholder] to avoid - /// show any placeholder where is not needed + /// This method creates a visual representation of the placeholder based on + /// the block attribute and style configurations provided. Use [shouldShowPlaceholder] + /// before invoking this method to ensure the placeholder is needed. @experimental WidgetSpan? build({ required Attribute blockAttribute, @@ -73,11 +87,11 @@ class PlaceholderBuilder { final configuration = builders[blockAttribute.key]?.call(blockAttribute, lineStyle); // we don't need to add a placeholder that is null or contains a empty text - if (configuration == null || configuration.placeholderText.trim().isEmpty) { + if (configuration == null || configuration.text.trim().isEmpty) { return null; } final textWidget = Text( - configuration.placeholderText, + configuration.text, style: configuration.style, textDirection: textDirection, softWrap: true, @@ -86,19 +100,9 @@ class PlaceholderBuilder { textScaler: textScaler, textWidthBasis: TextWidthBasis.longestLine, ); - // we use [Row] widget with [Expanded] to take whole the available width - // when the line has not defined an alignment. - // - // this behavior is different when the align is left or justify, because - // if we align the line to the center (example), row will take the whole - // width, creating a visual unexpected behavior where the caret being putted - // at the offset 0 (you can think this like the caret appears at the first char - // of the line when it is aligned at the left side instead appears at the middle - // if the line is centered) - // - // Note: - // this code is subject to changes because we need to get a better solution - // to this implementation + + // Use a [Row] with [Expanded] for placeholders in lines without explicit alignment. + // This ensures the placeholder spans the full width, avoiding unexpected alignment issues. return WidgetSpan( style: lineStyle, child: align == TextAlign.end || align == TextAlign.center diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart index 62ec314dc..73d32b8c8 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart @@ -1,9 +1,21 @@ -import 'package:flutter/material.dart' show TextStyle, immutable; +import 'package:flutter/material.dart' show TextStyle; +import 'package:meta/meta.dart' show experimental, immutable; import '../../../../document/attribute.dart'; typedef PlaceholderComponentBuilder = PlaceholderTextBuilder? Function( Attribute, TextStyle); +/// Configuration class for defining how placeholders are handled in the editor. +/// +/// The `PlaceholderConfig` allows customization of placeholder behavior by +/// providing builders for rendering specific components and defining custom +/// attribute keys that should be recognized during the placeholder build process. +/// +/// - [builders]: A map associating placeholder keys with their respective +/// component builders, allowing custom rendering logic. +/// - [customBlockAttributesKeys]: A set of additional attribute keys to include +/// in placeholder processing. By default, only predefined keys are considered. +@experimental @immutable class PlaceholderConfig { const PlaceholderConfig({ @@ -15,8 +27,7 @@ class PlaceholderConfig { return const PlaceholderConfig(builders: {}); } - /// These attributes are used with the default ones - /// to let us add placeholder to custom block attributes + /// Add custom keys here to include them in placeholder builds, as external keys are ignored by default. final Set? customBlockAttributesKeys; final Map builders; @@ -36,10 +47,10 @@ class PlaceholderConfig { @immutable class PlaceholderTextBuilder { const PlaceholderTextBuilder({ - required this.placeholderText, + required this.text, required this.style, }); - final String placeholderText; + final String text; final TextStyle style; } diff --git a/lib/src/editor/raw_editor/config/raw_editor_config.dart b/lib/src/editor/raw_editor/config/raw_editor_config.dart index 0e7d5d8bf..0561f413b 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_config.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_config.dart @@ -30,8 +30,8 @@ class QuillRawEditorConfig { required this.autoFocus, required this.characterShortcutEvents, required this.spaceShortcutEvents, - this.placeholderBuilder, - this.cursorPlaceholderConfig, + @experimental this.placeholderBuilder, + @experimental this.cursorPlaceholderConfig, @experimental this.onKeyPressed, this.showCursor = true, this.scrollable = true, @@ -108,10 +108,17 @@ class QuillRawEditorConfig { ///``` final List characterShortcutEvents; - /// Contains all necessary logic to build the placeholder - /// given for the devs + /// Configuration for displaying placeholders in empty lines or near the cursor. + @experimental final PlaceholderBuilder? placeholderBuilder; + /// Configures how a placeholder is displayed relative to the cursor. + /// + /// This argument specifies the appearance, style, and position of a placeholder + /// shown at the cursor's location in an empty line. + @experimental + final CursorPlaceholderConfig? cursorPlaceholderConfig; + /// Contains all the events that will be handled when /// space key is pressed /// @@ -134,8 +141,6 @@ class QuillRawEditorConfig { ///``` final List spaceShortcutEvents; - /// This argument configure how will be showed the placeholder at right or left of the cursor - final CursorPlaceholderConfig? cursorPlaceholderConfig; /// A handler for keys that are pressed when the editor is focused. /// diff --git a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart index 1fbc669a4..6a811f570 100644 --- a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart +++ b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart @@ -3,13 +3,12 @@ import 'package:flutter/material.dart'; const TextStyle _defaultPlaceholderStyle = TextStyle(color: Colors.grey, fontStyle: FontStyle.italic); -/// This class contains all necessary configurations -/// to show the wanted placeholder at the level of the cursor +/// Configuration for displaying a placeholder near the cursor in a rich text editor. /// -/// You can see this as some Rich Text Editors can contains a feature -/// where if the line is empty and not contains any block style (like -/// header, align, codeblock, etc), then will show a text -/// like (assume that "|" is the cursor): "| start writing" +/// The `CursorPlaceholderConfig` defines the appearance, position, and behavior +/// of a placeholder that is shown when a line is empty and the cursor is present. +/// This feature mimics behavior in some rich text editors where placeholder text +/// (e.g., "Start writing...") appears as a prompt when no content is entered. @immutable class CursorPlaceholderConfig { const CursorPlaceholderConfig({ @@ -19,6 +18,11 @@ class CursorPlaceholderConfig { required this.offset, }); + /// Creates a basic configuration for a cursor placeholder with default text and style. + /// + /// Parameters: + /// - [textStyle]: An optional custom style for the placeholder text. + /// Defaults to [_defaultPlaceholderStyle] if not provided. factory CursorPlaceholderConfig.basic({TextStyle? textStyle}) { return CursorPlaceholderConfig( text: 'Enter text...', @@ -37,17 +41,17 @@ class CursorPlaceholderConfig { ); } - /// The text that will be showed at the right + /// this text that will be showed at the right /// or left of the cursor final String text; - /// The textStyle of the placeholder + /// this is the text style of the placeholder final TextStyle textStyle; /// Decides if the placeholder should be showed final bool show; - /// Decides the offset where will be painted the text + /// The offset position where the placeholder text will be rendered. final Offset? offset; @override From 13f858b83df8e1d73deb01c9c3bc5ee0131fa89c Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Sun, 19 Jan 2025 14:47:43 -0400 Subject: [PATCH 109/113] Chore: dart format --- example/pubspec.lock | 30 ++++---- lib/src/editor/config/editor_config.dart | 69 +++++++++---------- lib/src/editor/editor.dart | 9 +-- .../placeholder/placeholder_builder.dart | 6 +- .../placeholder_configuration.dart | 8 +-- .../raw_editor/config/raw_editor_config.dart | 1 - .../cursor_configuration.dart | 4 +- 7 files changed, 61 insertions(+), 66 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index b0799b6fd..388701952 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" cross_file: dependency: transitive description: @@ -366,18 +366,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -534,7 +534,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -547,10 +547,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -563,10 +563,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" term_glyph: dependency: transitive description: @@ -579,10 +579,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" typed_data: dependency: transitive description: @@ -723,10 +723,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.0" web: dependency: transitive description: diff --git a/lib/src/editor/config/editor_config.dart b/lib/src/editor/config/editor_config.dart index 4776370ad..dfbef04d3 100644 --- a/lib/src/editor/config/editor_config.dart +++ b/lib/src/editor/config/editor_config.dart @@ -141,39 +141,39 @@ class QuillEditorConfig { @experimental final List spaceShortcutEvents; -/// Configuration for displaying placeholders in empty lines or near the cursor. -/// -/// ### Example -/// -/// To show a placeholder text specifically for header items: -/// -/// ```dart -/// final configuration = PlaceholderConfig( -/// builders: { -/// Attribute.header.key: (Attribute attr, style) { -/// final values = [30, 27, 22]; -/// final level = attr.value as int?; -/// if (level == null) return null; -/// final fontSize = values[(level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; -/// return PlaceholderTextBuilder( -/// text: 'Header $level', -/// style: TextStyle(fontSize: fontSize.toDouble()).merge(style), -/// ); -/// }, -/// }, -/// // If using custom attributes, register their keys here. -/// customBlockAttributesKeys: null, -/// ); -/// ``` -@experimental -final PlaceholderConfig? placeholderConfig; - -/// Configures how a placeholder is displayed relative to the cursor. -/// -/// This argument specifies the appearance, style, and position of a placeholder -/// shown at the cursor's location in an empty line. -@experimental -final CursorPlaceholderConfig? cursorPlaceholderConfig; + /// Configuration for displaying placeholders in empty lines or near the cursor. + /// + /// ### Example + /// + /// To show a placeholder text specifically for header items: + /// + /// ```dart + /// final configuration = PlaceholderConfig( + /// builders: { + /// Attribute.header.key: (Attribute attr, style) { + /// final values = [30, 27, 22]; + /// final level = attr.value as int?; + /// if (level == null) return null; + /// final fontSize = values[(level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; + /// return PlaceholderTextBuilder( + /// text: 'Header $level', + /// style: TextStyle(fontSize: fontSize.toDouble()).merge(style), + /// ); + /// }, + /// }, + /// // If using custom attributes, register their keys here. + /// customBlockAttributesKeys: null, + /// ); + /// ``` + @experimental + final PlaceholderConfig? placeholderConfig; + + /// Configures how a placeholder is displayed relative to the cursor. + /// + /// This argument specifies the appearance, style, and position of a placeholder + /// shown at the cursor's location in an empty line. + @experimental + final CursorPlaceholderConfig? cursorPlaceholderConfig; /// A handler for keys that are pressed when the editor is focused. /// @@ -556,8 +556,7 @@ final CursorPlaceholderConfig? cursorPlaceholderConfig; return QuillEditorConfig( cursorPlaceholderConfig: cursorPlaceholderConfig ?? this.cursorPlaceholderConfig, - placeholderConfig: placeholderConfig ?? - this.placeholderConfig, + placeholderConfig: placeholderConfig ?? this.placeholderConfig, customLeadingBlockBuilder: customLeadingBlockBuilder ?? this.customLeadingBlockBuilder, placeholder: placeholder ?? this.placeholder, diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 43ff71863..e348559c3 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -255,12 +255,9 @@ class QuillEditorState extends State final showSelectionToolbar = configurations.enableInteractiveSelection && configurations.enableSelectionToolbar; - final placeholderBuilder = - widget.config.placeholderConfig == null - ? null - : PlaceholderBuilder( - configuration: - widget.config.placeholderConfig!); + final placeholderBuilder = widget.config.placeholderConfig == null + ? null + : PlaceholderBuilder(configuration: widget.config.placeholderConfig!); final child = QuillRawEditor( key: _editorKey, controller: controller, diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart index 8ddc45347..cea92efb2 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_builder.dart @@ -19,8 +19,8 @@ final List _blackList = List.unmodifiable([ /// A utility class for managing placeholder rendering logic in a document editor. /// -/// The `PlaceholderBuilder` is responsible for determining when a placeholder -/// should be displayed in an empty node and for constructing the corresponding +/// The `PlaceholderBuilder` is responsible for determining when a placeholder +/// should be displayed in an empty node and for constructing the corresponding /// visual representation. /// /// - [configuration]: An instance of [PlaceholderConfig] containing placeholder @@ -43,7 +43,7 @@ class PlaceholderBuilder { /// /// This method checks if the node is empty and contains a block-level attribute /// matching a builder key or custom attribute, excluding keys in the blacklist. - /// + /// /// Returns a tuple: /// - [bool]: Whether a placeholder should be shown. /// - [String]: The key of the matching attribute, if applicable. diff --git a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart index 73d32b8c8..a9565b464 100644 --- a/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart +++ b/lib/src/editor/raw_editor/builders/placeholder/placeholder_configuration.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart' show TextStyle; +import 'package:flutter/material.dart' show TextStyle; import 'package:meta/meta.dart' show experimental, immutable; import '../../../../document/attribute.dart'; @@ -8,12 +8,12 @@ typedef PlaceholderComponentBuilder = PlaceholderTextBuilder? Function( /// Configuration class for defining how placeholders are handled in the editor. /// /// The `PlaceholderConfig` allows customization of placeholder behavior by -/// providing builders for rendering specific components and defining custom +/// providing builders for rendering specific components and defining custom /// attribute keys that should be recognized during the placeholder build process. /// -/// - [builders]: A map associating placeholder keys with their respective +/// - [builders]: A map associating placeholder keys with their respective /// component builders, allowing custom rendering logic. -/// - [customBlockAttributesKeys]: A set of additional attribute keys to include +/// - [customBlockAttributesKeys]: A set of additional attribute keys to include /// in placeholder processing. By default, only predefined keys are considered. @experimental @immutable diff --git a/lib/src/editor/raw_editor/config/raw_editor_config.dart b/lib/src/editor/raw_editor/config/raw_editor_config.dart index 0561f413b..77b4ef9da 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_config.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_config.dart @@ -141,7 +141,6 @@ class QuillRawEditorConfig { ///``` final List spaceShortcutEvents; - /// A handler for keys that are pressed when the editor is focused. /// /// This feature is supported on **desktop devices only**. diff --git a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart index 6a811f570..b1a0cd649 100644 --- a/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart +++ b/lib/src/editor/widgets/cursor_configuration/cursor_configuration.dart @@ -5,9 +5,9 @@ const TextStyle _defaultPlaceholderStyle = /// Configuration for displaying a placeholder near the cursor in a rich text editor. /// -/// The `CursorPlaceholderConfig` defines the appearance, position, and behavior +/// The `CursorPlaceholderConfig` defines the appearance, position, and behavior /// of a placeholder that is shown when a line is empty and the cursor is present. -/// This feature mimics behavior in some rich text editors where placeholder text +/// This feature mimics behavior in some rich text editors where placeholder text /// (e.g., "Start writing...") appears as a prompt when no content is entered. @immutable class CursorPlaceholderConfig { From dcbf188aa71bdbd0c6e2ecd9c773bef5d81983dc Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Mon, 20 Jan 2025 07:45:42 -0400 Subject: [PATCH 110/113] Chore(doc): added placeholder_introduction documentation --- doc/placeholders_introduction.md | 77 ++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 doc/placeholders_introduction.md diff --git a/doc/placeholders_introduction.md b/doc/placeholders_introduction.md new file mode 100644 index 000000000..e0d950eb5 --- /dev/null +++ b/doc/placeholders_introduction.md @@ -0,0 +1,77 @@ +# ✏️ Placeholders + +> A **placeholder** is visible text that serves as a guide or instruction for the user when a text field or editable area is empty. + +In **Flutter Quill**, there are three scenarios where **placeholders** can appear: + +- When the document is empty, a placeholder will appear at the beginning. +- When a dynamic placeholder is configured, it can display custom guide text anywhere in the document. +- When a cursor placeholder is set up, it appears whenever a line is completely empty. + +### 💡 How to Display a Placeholder When the Document is Empty + +To configure this, you need to use the `QuillEditorConfig` class: + +```dart +final config = QuillEditorConfig( + placeholder: 'Start writing your notes...', +); +``` + +### 🔎 What Are Dynamic Placeholders? + +**Dynamic placeholders** are not static or predetermined; they are **generated or adjusted automatically** based on the context of the content or the attributes applied to the text in the editor. + +These **placeholders** appear only when specific conditions are met, such as: + +- The block is empty. +- No additional text attributes (e.g., styles or links) are applied. + +#### 🛠️ How to Create a Dynamic Placeholder + +Here's a simple example: + +If you want to display guide text only when a header is applied and the line with this attribute is empty, you can use the following code: + +```dart +final config = QuillEditorConfig( + placeholderConfig: PlaceholderConfig( + builders: { + Attribute.header.key: (Attribute attr, TextStyle style) { + // In this case, we will only support header levels h1 to h3 + final values = [30, 27, 22]; + final level = attr.value as int?; + if (level == null) return null; + final fontSize = values[(level - 1 < 0 || level - 1 > 3 ? 0 : level - 1)]; + return PlaceholderTextBuilder( + text: 'Header $level', + style: TextStyle( + fontSize: fontSize.toDouble()) + .merge(style.copyWith( + color: Colors.grey)), + ); + }, + ), +); +``` + +### 🔎 What Are Cursor Placeholders? + +**Cursor placeholders** appear when a line is completely empty and has no attributes applied. These placeholders automatically appear at the same level as the cursor, though their position can be adjusted using the `offset` parameter in the `CursorPlaceholderConfig` class. + +Here's a simple implementation example: + +```dart +final config = QuillEditorConfig( + cursorPlaceholderConfig: CursorPlaceholderConfig( + text: 'Write something...', + textStyle: TextStyle( + color: Colors.grey, + fontStyle: FontStyle.italic, + ), + show: true, + offset: Offset(3.5, 2), + ), +); +``` + From 03bf936cd1db186a70c685460cb6748da74fa2cc Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Mon, 20 Jan 2025 08:17:39 -0400 Subject: [PATCH 111/113] Chore: update pubspec.lock --- example/pubspec.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index d08462048..d559cf44d 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -768,4 +768,4 @@ packages: version: "5.10.0" sdks: dart: ">=3.6.0 <4.0.0" - flutter: ">=3.27.0" \ No newline at end of file + flutter: ">=3.27.0" From 7500ddb9805a478b248ad8bcd808f87602930146 Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Mon, 20 Jan 2025 08:22:48 -0400 Subject: [PATCH 112/113] Chore: updated changelog to the current version in stable release --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96a2e2217..410e2c900 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +he format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). > [!NOTE] From cf20894efdfa147d450689c546230d914be5405e Mon Sep 17 00:00:00 2001 From: CatHood0 Date: Mon, 20 Jan 2025 08:23:27 -0400 Subject: [PATCH 113/113] Chore: added missed letter in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 410e2c900..96a2e2217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -he format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). > [!NOTE]