From 2ef44bbb3bca0259b9c7c533abee4d5244785b88 Mon Sep 17 00:00:00 2001 From: Hamza-Bayar <21060638@stu.omu.edu.tr> Date: Mon, 23 Jun 2025 11:15:30 +0300 Subject: [PATCH 1/8] Move the selection color behind the text --- example/.metadata | 25 +++------------ example/pubspec.lock | 2 +- lib/src/editor/widgets/text/text_line.dart | 36 ++++++++++------------ 3 files changed, 23 insertions(+), 40 deletions(-) diff --git a/example/.metadata b/example/.metadata index c2aa44bdb..a4934ec1a 100644 --- a/example/.metadata +++ b/example/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: "603104015dd692ea3403755b55d07813d5cf8965" + revision: "6fba2447e95c451518584c35e25f5433f14d888c" channel: "stable" project_type: app @@ -13,26 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: android - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: ios - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: linux - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: macos - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + create_revision: 6fba2447e95c451518584c35e25f5433f14d888c + base_revision: 6fba2447e95c451518584c35e25f5433f14d888c - platform: web - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: windows - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + create_revision: 6fba2447e95c451518584c35e25f5433f14d888c + base_revision: 6fba2447e95c451518584c35e25f5433f14d888c # User provided section diff --git a/example/pubspec.lock b/example/pubspec.lock index 766a88d90..3f68a94fc 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -767,5 +767,5 @@ packages: source: hosted version: "5.10.1" sdks: - dart: ">=3.6.0 <4.0.0" + dart: ">=3.7.0-0 <4.0.0" flutter: ">=3.27.0" diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index ee09dcc49..f501a7a9d 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -1396,25 +1396,7 @@ class RenderEditableTextLine extends RenderEditableBox { } } } - } - - if (hasFocus && - cursorCont.show.value && - containsCursor() && - !cursorCont.style.paintAboveText) { - _paintCursor(context, effectiveOffset, line.hasEmbed); - } - - context.paintChild(_body!, effectiveOffset); - - if (hasFocus && - cursorCont.show.value && - containsCursor() && - cursorCont.style.paintAboveText) { - _paintCursor(context, effectiveOffset, line.hasEmbed); - } - - // paint the selection on the top + } // paint the selection behind the text if (enableInteractiveSelection && line.documentOffset <= textSelection.end && textSelection.start <= line.documentOffset + line.length - 1) { @@ -1446,6 +1428,22 @@ class RenderEditableTextLine extends RenderEditableBox { _paintSelection(context, effectiveOffset); } + + if (hasFocus && + cursorCont.show.value && + containsCursor() && + !cursorCont.style.paintAboveText) { + _paintCursor(context, effectiveOffset, line.hasEmbed); + } + + context.paintChild(_body!, effectiveOffset); + + if (hasFocus && + cursorCont.show.value && + containsCursor() && + cursorCont.style.paintAboveText) { + _paintCursor(context, effectiveOffset, line.hasEmbed); + } } } From f7ca57aaf872cbe18a23a0a953f46ba69cc26526 Mon Sep 17 00:00:00 2001 From: Hamza-Bayar-2 Date: Mon, 23 Jun 2025 14:50:57 +0300 Subject: [PATCH 2/8] Add paintSelectionBehindText configuration option --- example/pubspec.lock | 92 ++++---- lib/src/editor/config/editor_config.dart | 9 + lib/src/editor/editor.dart | 1 + .../raw_editor/config/raw_editor_config.dart | 6 + .../editor/raw_editor/raw_editor_state.dart | 31 +-- lib/src/editor/widgets/text/text_block.dart | 6 +- lib/src/editor/widgets/text/text_line.dart | 204 ++++++++++++------ 7 files changed, 221 insertions(+), 128 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index 3f68a94fc..dd995ef31 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -13,26 +13,26 @@ packages: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.13.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" characters: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" charcode: dependency: transitive description: @@ -45,18 +45,18 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.19.0" + version: "1.19.1" cross_file: dependency: transitive description: @@ -93,10 +93,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" ffi: dependency: transitive description: @@ -109,10 +109,10 @@ packages: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" file_selector_linux: dependency: transitive description: @@ -365,26 +365,26 @@ packages: dependency: transitive description: name: intl - sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" url: "https://pub.dev" source: hosted - version: "0.19.0" + version: "0.20.2" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" url: "https://pub.dev" source: hosted - version: "10.0.7" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: @@ -413,10 +413,10 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -429,10 +429,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" mime: dependency: transitive description: @@ -445,10 +445,10 @@ packages: dependency: "direct main" description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" photo_view: dependency: transitive description: @@ -461,10 +461,10 @@ packages: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -477,10 +477,10 @@ packages: dependency: transitive description: name: process - sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" + sha256: "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d" url: "https://pub.dev" source: hosted - version: "5.0.2" + version: "5.0.3" quill_native_bridge: dependency: transitive description: @@ -562,34 +562,34 @@ packages: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" stack_trace: dependency: transitive description: name: stack_trace - sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" string_scanner: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.1" sync_http: dependency: transitive description: @@ -602,18 +602,18 @@ packages: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.3" + version: "0.7.4" typed_data: dependency: transitive description: @@ -738,10 +738,10 @@ packages: dependency: transitive description: name: vm_service - sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "14.3.0" + version: "15.0.0" web: dependency: transitive description: @@ -754,10 +754,10 @@ packages: dependency: transitive description: name: webdriver - sha256: "3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8" + sha256: "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade" url: "https://pub.dev" source: hosted - version: "3.0.4" + version: "3.1.0" win32: dependency: transitive description: diff --git a/lib/src/editor/config/editor_config.dart b/lib/src/editor/config/editor_config.dart index 89b0813c4..631c25292 100644 --- a/lib/src/editor/config/editor_config.dart +++ b/lib/src/editor/config/editor_config.dart @@ -42,6 +42,7 @@ class QuillEditorConfig { this.paintCursorAboveText, this.enableInteractiveSelection = true, this.enableSelectionToolbar = true, + this.paintSelectionBehindText = true, this.scrollBottomInset = 0, this.minHeight, this.maxHeight, @@ -269,6 +270,11 @@ class QuillEditorConfig { /// Whether to show the cut/copy/paste menu when selecting text. final bool enableSelectionToolbar; + /// Whether to paint the selection behind the text (true) or in front of the text (false). + /// When true, the selection color can be opaque. When false, the selection color should be transparent. + /// Defaults to true. + final bool paintSelectionBehindText; + /// The minimum height to be occupied by this editor. /// /// This only has effect if [scrollable] is set to `true` and [expands] is @@ -494,6 +500,7 @@ class QuillEditorConfig { MouseCursor? readOnlyMouseCursor, bool? enableInteractiveSelection, bool? enableSelectionToolbar, + bool? paintSelectionBehindText, double? minHeight, double? maxHeight, double? maxContentWidth, @@ -557,6 +564,8 @@ class QuillEditorConfig { enableInteractiveSelection ?? this.enableInteractiveSelection, enableSelectionToolbar: enableSelectionToolbar ?? this.enableSelectionToolbar, + paintSelectionBehindText: + paintSelectionBehindText ?? this.paintSelectionBehindText, minHeight: minHeight ?? this.minHeight, maxHeight: maxHeight ?? this.maxHeight, maxContentWidth: maxContentWidth ?? this.maxContentWidth, diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 3f8831a3b..9e0b8d112 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -303,6 +303,7 @@ class QuillEditorState extends State expands: config.expands, autoFocus: config.autoFocus, selectionColor: selectionColor, + paintSelectionBehindText: config.paintSelectionBehindText, selectionCtrls: config.textSelectionControls ?? textSelectionControls, keyboardAppearance: config.keyboardAppearance, enableInteractiveSelection: config.enableInteractiveSelection, 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 98358d179..0f238afe7 100644 --- a/lib/src/editor/raw_editor/config/raw_editor_config.dart +++ b/lib/src/editor/raw_editor/config/raw_editor_config.dart @@ -29,6 +29,7 @@ class QuillRawEditorConfig { required this.embedBuilder, required this.textSpanBuilder, required this.autoFocus, + this.paintSelectionBehindText = true, this.characterShortcutEvents = const [], this.spaceShortcutEvents = const [], @experimental this.onKeyPressed, @@ -303,6 +304,11 @@ class QuillRawEditorConfig { /// The color to use when painting the selection. final Color selectionColor; + /// Whether to paint the selection behind the text (true) or in front of the text (false). + /// When true, the selection color can be opaque. When false, the selection color should be transparent. + /// Defaults to true. + final bool paintSelectionBehindText; + /// Delegate for building the text selection handles and toolbar. /// /// The [QuillRawEditor] widget used on its own will not trigger the display diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index cdc9793e5..f04ccf12e 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -653,6 +653,7 @@ class QuillRawEditorState extends EditorState color: widget.config.selectionColor, styles: _styles, enableInteractiveSelection: widget.config.enableInteractiveSelection, + paintSelectionBehindText: widget.config.paintSelectionBehindText, hasFocus: _hasFocus, contentPadding: attrs.containsKey(Attribute.codeBlock.key) ? const EdgeInsets.all(16) @@ -707,20 +708,22 @@ class QuillRawEditorState extends EditorState composingRange: composingRange.value, ); final editableTextLine = EditableTextLine( - node, - null, - textLine, - _getHorizontalSpacingForLine(node, _styles), - _getVerticalSpacingForLine(node, _styles), - _textDirection, - controller.selection, - widget.config.selectionColor, - widget.config.enableInteractiveSelection, - _hasFocus, - MediaQuery.devicePixelRatioOf(context), - _cursorCont, - _styles!.inlineCode!, - _getDecoration(node, _styles, attrs)); + node, + null, + textLine, + _getHorizontalSpacingForLine(node, _styles), + _getVerticalSpacingForLine(node, _styles), + _textDirection, + controller.selection, + widget.config.selectionColor, + widget.config.enableInteractiveSelection, + _hasFocus, + MediaQuery.devicePixelRatioOf(context), + _cursorCont, + _styles!.inlineCode!, + _getDecoration(node, _styles, attrs), + widget.config.paintSelectionBehindText, + ); return editableTextLine; } diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index 01a4208e4..6ce9a1cf3 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -67,6 +67,7 @@ class EditableTextBlock extends StatelessWidget { required this.color, required this.styles, required this.enableInteractiveSelection, + required this.paintSelectionBehindText, required this.hasFocus, required this.contentPadding, required this.embedBuilder, @@ -98,6 +99,7 @@ class EditableTextBlock extends StatelessWidget { final DefaultStyles? styles; final LeadingBlockNodeBuilder? customLeadingBlockBuilder; final bool enableInteractiveSelection; + final bool paintSelectionBehindText; final bool hasFocus; final EdgeInsets? contentPadding; final EmbedsBuilder embedBuilder; @@ -209,7 +211,9 @@ class EditableTextBlock extends StatelessWidget { MediaQuery.devicePixelRatioOf(context), cursorCont, styles!.inlineCode!, - null); + null, + paintSelectionBehindText, + ); final nodeTextDirection = getDirectionOfNode(line, textDirection); children.add( Directionality( diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index f501a7a9d..1eb788693 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -725,21 +725,23 @@ class _TextLineState extends State { class EditableTextLine extends RenderObjectWidget { const EditableTextLine( - this.line, - this.leading, - this.body, - this.horizontalSpacing, - this.verticalSpacing, - this.textDirection, - this.textSelection, - this.color, - this.enableInteractiveSelection, - this.hasFocus, - this.devicePixelRatio, - this.cursorCont, - this.inlineCodeStyle, - this.decoration, - {super.key}); + this.line, + this.leading, + this.body, + this.horizontalSpacing, + this.verticalSpacing, + this.textDirection, + this.textSelection, + this.color, + this.enableInteractiveSelection, + this.hasFocus, + this.devicePixelRatio, + this.cursorCont, + this.inlineCodeStyle, + this.decoration, + this.paintSelectionBehindText, { + super.key, + }); final Line line; final Widget? leading; @@ -755,6 +757,7 @@ class EditableTextLine extends RenderObjectWidget { final CursorCont cursorCont; final InlineCodeStyle inlineCodeStyle; final BoxDecoration? decoration; + final bool paintSelectionBehindText; @override RenderObjectElement createElement() { @@ -764,17 +767,19 @@ class EditableTextLine extends RenderObjectWidget { @override RenderObject createRenderObject(BuildContext context) { return RenderEditableTextLine( - line, - textDirection, - textSelection, - enableInteractiveSelection, - hasFocus, - devicePixelRatio, - _getPadding(), - color, - cursorCont, - inlineCodeStyle, - decoration); + line, + textDirection, + textSelection, + enableInteractiveSelection, + hasFocus, + devicePixelRatio, + _getPadding(), + color, + cursorCont, + inlineCodeStyle, + decoration, + paintSelectionBehindText, + ); } @override @@ -791,7 +796,10 @@ class EditableTextLine extends RenderObjectWidget { ..setDevicePixelRatio(devicePixelRatio) ..setCursorCont(cursorCont) ..setInlineCodeStyle(inlineCodeStyle) - ..setDecoration(decoration); + ..setDecoration(decoration) + ..setPaintSelectionBehindText( + paintSelectionBehindText, + ); } EdgeInsetsGeometry _getPadding() { @@ -819,6 +827,7 @@ class RenderEditableTextLine extends RenderEditableBox { this.cursorCont, this.inlineCodeStyle, this.decoration, + this.paintSelectionBehindText, ); RenderBox? _leading; @@ -838,6 +847,7 @@ class RenderEditableTextLine extends RenderEditableBox { late Rect _caretPrototype; InlineCodeStyle inlineCodeStyle; BoxDecoration? decoration; + bool paintSelectionBehindText; final Map children = {}; Iterable get _children sync* { @@ -959,6 +969,12 @@ class RenderEditableTextLine extends RenderEditableBox { markNeedsPaint(); } + void setPaintSelectionBehindText(bool newValue) { + if (paintSelectionBehindText == newValue) return; + paintSelectionBehindText = newValue; + markNeedsPaint(); + } + // Start selection implementation bool containsTextSelection() { @@ -1396,53 +1412,107 @@ class RenderEditableTextLine extends RenderEditableBox { } } } - } // paint the selection behind the text - if (enableInteractiveSelection && - line.documentOffset <= textSelection.end && - textSelection.start <= line.documentOffset + line.length - 1) { - final local = localSelection(line, textSelection, false); - _selectedRects ??= _body!.getBoxesForSelection( - local, - ); + } - // Paint a small rect at the start of empty lines that - // are contained by the selection. - if (line.isEmpty && - textSelection.baseOffset <= line.offset && - textSelection.extentOffset > line.offset) { - final lineHeight = preferredLineHeight( - TextPosition( - offset: line.offset, - ), - ); - _selectedRects?.add( - TextBox.fromLTRBD( - 0, - 0, - 3, - lineHeight, - textDirection, - ), + // Paint selection and text based on paintSelectionBehindText setting + if (paintSelectionBehindText) { + // Paint selection behind text (new behavior) + if (enableInteractiveSelection && + line.documentOffset <= textSelection.end && + textSelection.start <= line.documentOffset + line.length - 1) { + final local = localSelection(line, textSelection, false); + _selectedRects ??= _body!.getBoxesForSelection( + local, ); + + // Paint a small rect at the start of empty lines that + // are contained by the selection. + if (line.isEmpty && + textSelection.baseOffset <= line.offset && + textSelection.extentOffset > line.offset) { + final lineHeight = preferredLineHeight( + TextPosition( + offset: line.offset, + ), + ); + _selectedRects?.add( + TextBox.fromLTRBD( + 0, + 0, + 3, + lineHeight, + textDirection, + ), + ); + } + + _paintSelection(context, effectiveOffset); } - _paintSelection(context, effectiveOffset); - } + if (hasFocus && + cursorCont.show.value && + containsCursor() && + !cursorCont.style.paintAboveText) { + _paintCursor(context, effectiveOffset, line.hasEmbed); + } - if (hasFocus && - cursorCont.show.value && - containsCursor() && - !cursorCont.style.paintAboveText) { - _paintCursor(context, effectiveOffset, line.hasEmbed); - } + context.paintChild(_body!, effectiveOffset); - context.paintChild(_body!, effectiveOffset); + if (hasFocus && + cursorCont.show.value && + containsCursor() && + cursorCont.style.paintAboveText) { + _paintCursor(context, effectiveOffset, line.hasEmbed); + } + } else { + // Paint selection in front of text (old behavior) + if (hasFocus && + cursorCont.show.value && + containsCursor() && + !cursorCont.style.paintAboveText) { + _paintCursor(context, effectiveOffset, line.hasEmbed); + } + + context.paintChild(_body!, effectiveOffset); - if (hasFocus && - cursorCont.show.value && - containsCursor() && - cursorCont.style.paintAboveText) { - _paintCursor(context, effectiveOffset, line.hasEmbed); + if (hasFocus && + cursorCont.show.value && + containsCursor() && + cursorCont.style.paintAboveText) { + _paintCursor(context, effectiveOffset, line.hasEmbed); + } + + if (enableInteractiveSelection && + line.documentOffset <= textSelection.end && + textSelection.start <= line.documentOffset + line.length - 1) { + final local = localSelection(line, textSelection, false); + _selectedRects ??= _body!.getBoxesForSelection( + local, + ); + + // Paint a small rect at the start of empty lines that + // are contained by the selection. + if (line.isEmpty && + textSelection.baseOffset <= line.offset && + textSelection.extentOffset > line.offset) { + final lineHeight = preferredLineHeight( + TextPosition( + offset: line.offset, + ), + ); + _selectedRects?.add( + TextBox.fromLTRBD( + 0, + 0, + 3, + lineHeight, + textDirection, + ), + ); + } + + _paintSelection(context, effectiveOffset); + } } } } From 08d8c55e049367af46f36501d7f3b6c811e74d56 Mon Sep 17 00:00:00 2001 From: Hamza-Bayar-2 Date: Wed, 25 Jun 2025 18:32:07 +0300 Subject: [PATCH 3/8] feat: implement drag selection tracking and smooth scrolling for web --- lib/src/controller/quill_controller.dart | 45 +++++++++++++++++++ lib/src/editor/editor.dart | 22 +++++++-- .../raw_editor/raw_editor_render_object.dart | 4 ++ .../editor/raw_editor/raw_editor_state.dart | 2 + 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/lib/src/controller/quill_controller.dart b/lib/src/controller/quill_controller.dart index 0d2d291a4..0a41ff186 100644 --- a/lib/src/controller/quill_controller.dart +++ b/lib/src/controller/quill_controller.dart @@ -96,6 +96,46 @@ class QuillController extends ChangeNotifier { TextSelection get selection => _selection; TextSelection _selection; + // Drag selection tracking for smooth scrolling on web + bool _isDragging = false; + TextSelection? _previousSelection; + + bool get isDragging => _isDragging; + + void startDragSelection() { + _isDragging = true; + _previousSelection = _selection; + } + + void endDragSelection() { + _isDragging = false; + _previousSelection = null; + } + + /// Get the appropriate caret position for scrolling during drag selection + TextPosition getCaretPositionForScrolling() { + if (!_isDragging || _previousSelection == null) { + return _selection.extent; + } + + final oldSelection = _previousSelection!; + final newSelection = _selection; + + // Did the base position change? + if (oldSelection.baseOffset != newSelection.baseOffset) { + // Base changed, track the base position + return newSelection.base; + } + // Did the extent position change? + else if (oldSelection.extentOffset != newSelection.extentOffset) { + // Extent changed, track the extent position + return newSelection.extent; + } + + // If no change, use extent + return newSelection.extent; + } + /// Custom [replaceText] handler /// Return false to ignore the event ReplaceTextCallback? onReplaceText; @@ -463,6 +503,11 @@ class QuillController extends ChangeNotifier { void _updateSelection(TextSelection textSelection, {bool insertNewline = false}) { + // Drag sırasında önceki selection'ı güncelle + if (_isDragging) { + _previousSelection = _selection; + } + _selection = textSelection; final end = document.length - 1; _selection = selection.copyWith( diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 9e0b8d112..a2a9ae160 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -681,6 +681,7 @@ class RenderEditor extends RenderEditableContainerBox required this.onSelectionCompleted, required super.scrollBottomInset, required this.floatingCursorDisabled, + this.controller, ViewportOffset? offset, super.children, EdgeInsets floatingCursorAddedMargin = @@ -696,6 +697,7 @@ class RenderEditor extends RenderEditableContainerBox container: document.root, ); + final QuillController? controller; final CursorCont _cursorController; final bool floatingCursorDisabled; final bool scrollable; @@ -924,6 +926,8 @@ class RenderEditor extends RenderEditableContainerBox void handleDragStart(DragStartDetails details) { _isDragging = true; + // Notify controller that drag has started + controller?.startDragSelection(); final newSelection = selectPositionAt( from: details.globalPosition, @@ -937,6 +941,8 @@ class RenderEditor extends RenderEditableContainerBox void handleDragEnd(DragEndDetails details) { _isDragging = false; + // Notify controller that drag has ended + controller?.endDragSelection(); onSelectionCompleted(); } @@ -1234,9 +1240,19 @@ class RenderEditor extends RenderEditableContainerBox return childLocalRect.shift(Offset(0, boxParentData.offset.dy)); } - TextPosition get caretTextPosition => _floatingCursorRect == null - ? selection.extent - : _floatingCursorTextPosition; + TextPosition get caretTextPosition { + if (_floatingCursorRect != null) { + return _floatingCursorTextPosition; + } + + // Get smart caret position from controller during drag on web platform + if (kIsWeb && controller != null && controller!.isDragging) { + return controller!.getCaretPositionForScrolling(); + } + + // Use extent in normal cases (cursor position) + return selection.extent; + } // Start floating cursor diff --git a/lib/src/editor/raw_editor/raw_editor_render_object.dart b/lib/src/editor/raw_editor/raw_editor_render_object.dart index d79536210..ab3b4c8ec 100644 --- a/lib/src/editor/raw_editor/raw_editor_render_object.dart +++ b/lib/src/editor/raw_editor/raw_editor_render_object.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart' show ViewportOffset; +import '../../controller/quill_controller.dart'; import '../../document/document.dart'; import '../editor.dart'; import '../widgets/cursor.dart'; @@ -21,6 +22,7 @@ class QuillRawEditorMultiChildRenderObject required this.scrollBottomInset, required this.cursorController, required this.floatingCursorDisabled, + this.controller, super.key, this.padding = EdgeInsets.zero, this.maxContentWidth, @@ -42,6 +44,7 @@ class QuillRawEditorMultiChildRenderObject final double? maxContentWidth; final CursorCont cursorController; final bool floatingCursorDisabled; + final QuillController? controller; @override RenderEditor createRenderObject(BuildContext context) { @@ -61,6 +64,7 @@ class QuillRawEditorMultiChildRenderObject maxContentWidth: maxContentWidth, scrollBottomInset: scrollBottomInset, floatingCursorDisabled: floatingCursorDisabled, + controller: controller, ); } diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index f04ccf12e..baacd0b4c 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -477,6 +477,7 @@ class QuillRawEditorState extends EditorState cursorController: _cursorCont, floatingCursorDisabled: widget.config.floatingCursorDisabled, + controller: controller, children: _buildChildren(doc, context), ), ), @@ -508,6 +509,7 @@ class QuillRawEditorState extends EditorState padding: widget.config.padding, maxContentWidth: widget.config.maxContentWidth, floatingCursorDisabled: widget.config.floatingCursorDisabled, + controller: controller, children: _buildChildren(doc, context), ), ), From d5d62f1f01aca8c48e830edb1be52138b1092895 Mon Sep 17 00:00:00 2001 From: Hamza-Bayar-2 Date: Wed, 2 Jul 2025 10:04:41 +0300 Subject: [PATCH 4/8] fix: update flutter_quill and flutter_quill_extensions to use git dependencies --- example/pubspec.yaml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index ac5083005..15a70538e 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -13,8 +13,13 @@ dependencies: flutter_localizations: sdk: flutter - flutter_quill: ^11.0.0-dev.4 - flutter_quill_extensions: ^11.0.0-dev.3 + flutter_quill: + git: + url: git@github.com:singerdmx/flutter-quill.git + flutter_quill_extensions: + git: + url: git@github.com:singerdmx/flutter-quill.git + path: flutter_quill_extensions path: ^1.9.0 dev_dependencies: From 4bb77f6b71ff0fa65c0f358f2e6e62665ba964eb Mon Sep 17 00:00:00 2001 From: Hamza-Bayar-2 Date: Wed, 2 Jul 2025 10:16:06 +0300 Subject: [PATCH 5/8] Update pubspec.yaml package version --- example/pubspec.lock | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index dd995ef31..49d5a8ff5 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -230,7 +230,7 @@ packages: path: ".." relative: true source: path - version: "11.4.1" + version: "11.4.1+fork" flutter_quill_delta_from_html: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b0decd6da..320d6dddb 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: 11.4.1 +version: 11.4.1+fork homepage: https://github.com/singerdmx/flutter-quill/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ From 1203a40596f988813eca60480e66786114f7a7a8 Mon Sep 17 00:00:00 2001 From: Hamza-Bayar-2 Date: Wed, 2 Jul 2025 10:22:38 +0300 Subject: [PATCH 6/8] Update flutter_quill_extensions version to 11.0.0+fork --- example/pubspec.lock | 2 +- flutter_quill_extensions/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index 49d5a8ff5..d30436791 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -245,7 +245,7 @@ packages: path: "../flutter_quill_extensions" relative: true source: path - version: "11.0.0" + version: "11.0.0+fork" flutter_quill_test: dependency: "direct dev" description: diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 6f5cae329..fb4dd6cfc 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 to support loading images and videos -version: 11.0.0 +version: 11.0.0+fork 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/ From 30997417279331e23dccaa51b52686662534dafb Mon Sep 17 00:00:00 2001 From: Hamza-Bayar-2 Date: Wed, 2 Jul 2025 11:03:08 +0300 Subject: [PATCH 7/8] Update flutter_quill dependency to use local path --- flutter_quill_extensions/pubspec.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index fb4dd6cfc..2eb0d27eb 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,3 +1,5 @@ +publish_to: none + name: flutter_quill_extensions description: Embed extensions for flutter_quill to support loading images and videos version: 11.0.0+fork @@ -36,7 +38,8 @@ dependencies: web: ">=0.5.0 <2.0.0" path: ^1.8.0 - flutter_quill: ^11.0.0 + flutter_quill: + path: ../ photo_view: ^0.15.0 # Plugins From 2fd38a5ef41fcf2225fd5fb01cf0884089d2bf82 Mon Sep 17 00:00:00 2001 From: Hamza-Bayar-2 Date: Sat, 5 Jul 2025 00:32:38 +0300 Subject: [PATCH 8/8] Small fix --- example/pubspec.lock | 94 +++++++++++++-------------- flutter_quill_extensions/pubspec.yaml | 5 +- 2 files changed, 48 insertions(+), 51 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index d30436791..25b1312ce 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -13,26 +13,26 @@ packages: dependency: transitive description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.13.0" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" characters: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.3.0" charcode: dependency: transitive description: @@ -45,18 +45,18 @@ packages: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.1" collection: dependency: transitive description: name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.19.1" + version: "1.19.0" cross_file: dependency: transitive description: @@ -93,10 +93,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" url: "https://pub.dev" source: hosted - version: "1.3.3" + version: "1.3.1" ffi: dependency: transitive description: @@ -109,10 +109,10 @@ packages: dependency: transitive description: name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "7.0.0" file_selector_linux: dependency: transitive description: @@ -365,26 +365,26 @@ packages: dependency: transitive description: name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.20.2" + version: "0.19.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.9" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -413,10 +413,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: @@ -429,10 +429,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.15.0" mime: dependency: transitive description: @@ -445,10 +445,10 @@ packages: dependency: "direct main" description: name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.9.0" photo_view: dependency: transitive description: @@ -461,10 +461,10 @@ packages: dependency: transitive description: name: platform - sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" url: "https://pub.dev" source: hosted - version: "3.1.6" + version: "3.1.5" plugin_platform_interface: dependency: transitive description: @@ -477,10 +477,10 @@ packages: dependency: transitive description: name: process - sha256: "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d" + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted - version: "5.0.3" + version: "5.0.2" quill_native_bridge: dependency: transitive description: @@ -562,34 +562,34 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.12.1" + version: "1.12.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.2" string_scanner: dependency: transitive description: name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.3.0" sync_http: dependency: transitive description: @@ -602,18 +602,18 @@ packages: dependency: transitive description: name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.3" typed_data: dependency: transitive description: @@ -738,10 +738,10 @@ packages: dependency: transitive description: name: vm_service - sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "15.0.0" + version: "14.3.0" web: dependency: transitive description: @@ -754,10 +754,10 @@ packages: dependency: transitive description: name: webdriver - sha256: "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade" + sha256: "3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.0.4" win32: dependency: transitive description: @@ -767,5 +767,5 @@ packages: source: hosted version: "5.10.1" sdks: - dart: ">=3.7.0-0 <4.0.0" + dart: ">=3.6.0 <4.0.0" flutter: ">=3.27.0" diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 2eb0d27eb..fb4dd6cfc 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,5 +1,3 @@ -publish_to: none - name: flutter_quill_extensions description: Embed extensions for flutter_quill to support loading images and videos version: 11.0.0+fork @@ -38,8 +36,7 @@ dependencies: web: ">=0.5.0 <2.0.0" path: ^1.8.0 - flutter_quill: - path: ../ + flutter_quill: ^11.0.0 photo_view: ^0.15.0 # Plugins