From 13f0a2c702896ae534d82cd7e72eaa95c0620e48 Mon Sep 17 00:00:00 2001
From: Cierra_Runis <2864283875@qq.com>
Date: Wed, 1 Feb 2023 21:07:13 +0800
Subject: [PATCH 01/25] Alert (#1076)
---
README.md | 6 +++---
doc_cn.md | 24 ++++++++++++++----------
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/README.md b/README.md
index b5f5e1dd..5ec17c82 100644
--- a/README.md
+++ b/README.md
@@ -383,10 +383,10 @@ The translation file is located at [toolbar.i18n.dart](lib/src/translations/tool
Having your document stored in Quill Delta format is sometimes not enough. Often you'll need to convert
it to other formats such as HTML in order to publish it, or send an email. One 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.
+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.
+Typescript/Javascript package.
## Sponsors
diff --git a/doc_cn.md b/doc_cn.md
index 870ce674..01375221 100644
--- a/doc_cn.md
+++ b/doc_cn.md
@@ -187,7 +187,7 @@ QuillToolbar.basic(
若需要图片、视频、公式块的支持,请查看独立库 [`flutter_quill_extensions`](https://pub.dev/packages/flutter_quill_extensions)
-### 根据 `flutter_quill_extensions` 使用自定义嵌入块
+### 根据 `flutter_quill_extensions` 使用图片、视频、公式等自定义嵌入块
```dart
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
@@ -355,7 +355,7 @@ QuillToolbar(locale: Locale('fr'), ...)
QuillEditor(locale: Locale('fr'), ...)
```
-目前,可提供以下 24 种语言环境的翻译:
+目前,可提供以下 25 种语言环境的翻译:
* `Locale('en')`
* `Locale('ar')`
@@ -363,6 +363,7 @@ QuillEditor(locale: Locale('fr'), ...)
* `Locale('de')`
* `Locale('da')`
* `Locale('fr')`
+* `Locale('he')`
* `Locale('zh', 'cn')`
* `Locale('zh', 'hk')`
* `Locale('ko')`
@@ -384,20 +385,23 @@ QuillEditor(locale: Locale('fr'), ...)
#### 贡献翻译
-翻译文件位于 [toolbar.i18n.dart](lib/src/translations/toolbar.i18n.dart)。
+翻译文件位于 [toolbar.i18n.dart](lib/src/translations/toolbar.i18n.dart)
-随意贡献你自己的翻译,只需复制英文翻译映射并将值替换为你的翻译即可。
+随意贡献你自己的翻译,只需复制英文翻译映射并将值替换为你的翻译即可
然后打开一个拉取请求,这样每个人都可以从你的翻译中受益!
----
+### 转化至 HTML
-## 帮助
+将你的文档转为 `Quill Delta` 格式有时还不够,通常你需要将其转化为其他如 `HTML` 格式来分发他,或作为邮件发出
-
-
+一个方案是使用 [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html) `Flutter` 包来转化至 `HTML` 格式。此包支持所以的 `Quill` 操作,包含图片、视频、公式、表格和注释
+
+转化过程可以在 `vanilla Dart` 如服务器端或 `CLI` 执行,也可在 `Flutter` 中执行
+
+其是流行且成熟的 [quill-delta-to-html](https://www.npmjs.com/package/quill-delta-to-html) `Typescript/Javascript` 包的 `Dart` 部分
+
+---
## 赞助
From 11f65f9872f1e35aa05565726fd102225d95758e Mon Sep 17 00:00:00 2001
From: Anti-Core <71420694+1252158112@users.noreply.github.com>
Date: Wed, 1 Feb 2023 23:41:15 +0800
Subject: [PATCH 02/25] fix error style when input chinese japanese or korean
(#1078)
---
lib/src/models/rules/insert.dart | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/src/models/rules/insert.dart b/lib/src/models/rules/insert.dart
index ef77e77a..949371b5 100644
--- a/lib/src/models/rules/insert.dart
+++ b/lib/src/models/rules/insert.dart
@@ -477,7 +477,7 @@ class PreserveInlineStylesRule extends InsertRule {
}
final itr = DeltaIterator(document);
- final prev = itr.skip(index);
+ final prev = itr.skip(len == 0 ? index : index + 1);
if (prev == null ||
prev.data is! String ||
(prev.data as String).contains('\n')) {
From d8b03675b5e744e52f3cc72127cd3deee6472189 Mon Sep 17 00:00:00 2001
From: X Code
Date: Wed, 1 Feb 2023 08:04:42 -0800
Subject: [PATCH 03/25] Upgrade to 6.3.2
---
CHANGELOG.md | 4 ++++
lib/src/widgets/editor.dart | 16 ++++++++--------
pubspec.yaml | 2 +-
3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0df24919..a7a5bd44 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# [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.
diff --git a/lib/src/widgets/editor.dart b/lib/src/widgets/editor.dart
index 7dae5136..4160e0bb 100644
--- a/lib/src/widgets/editor.dart
+++ b/lib/src/widgets/editor.dart
@@ -494,12 +494,12 @@ class QuillEditorState extends State
readOnly,
) =>
_buildCustomBlockEmbed(
- node,
- context,
- controller,
- readOnly,
- widget.unknownEmbedBuilder,
- ),
+ node,
+ context,
+ controller,
+ readOnly,
+ widget.unknownEmbedBuilder,
+ ),
linkActionPickerDelegate: widget.linkActionPickerDelegate,
customStyleBuilder: widget.customStyleBuilder,
floatingCursorDisabled: widget.floatingCursorDisabled,
@@ -541,7 +541,7 @@ class QuillEditorState extends State
EmbedsBuilder? unknownEmbedBuilder,
) {
final builders = widget.embedBuilders;
-
+
var _node = node;
// Creates correct node for custom embed
if (node.value.type == BlockEmbed.customType) {
@@ -555,7 +555,7 @@ class QuillEditorState extends State
}
}
}
-
+
if (unknownEmbedBuilder != null) {
return unknownEmbedBuilder(context, controller, _node, readOnly);
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 68f4cdfd..cd284606 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_quill
description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us)
-version: 6.3.1
+version: 6.3.2
#author: bulletjournal
homepage: https://bulletjournal.us/home/index.html
repository: https://github.com/singerdmx/flutter-quill
From 74544bd945a9d212ca1e8d6b3053dbecee22b720 Mon Sep 17 00:00:00 2001
From: Rajender Katkuri <76048287+rajenderK7@users.noreply.github.com>
Date: Wed, 1 Feb 2023 22:13:03 +0530
Subject: [PATCH 04/25] Remove transparent color of ImageVideoUtils dialog
(#1079)
---
.../lib/embeds/toolbar/image_video_utils.dart | 1 -
1 file changed, 1 deletion(-)
diff --git a/flutter_quill_extensions/lib/embeds/toolbar/image_video_utils.dart b/flutter_quill_extensions/lib/embeds/toolbar/image_video_utils.dart
index a72f1996..aef7c9e7 100644
--- a/flutter_quill_extensions/lib/embeds/toolbar/image_video_utils.dart
+++ b/flutter_quill_extensions/lib/embeds/toolbar/image_video_utils.dart
@@ -80,7 +80,6 @@ class ImageVideoUtils {
context: context,
builder: (ctx) => AlertDialog(
contentPadding: EdgeInsets.zero,
- backgroundColor: Colors.transparent,
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
From 0046ca6782dd6f9da95b724ecfc4c499f8cad119 Mon Sep 17 00:00:00 2001
From: Htoo Pyae Linn <85918337+htoopyaelinn56@users.noreply.github.com>
Date: Mon, 6 Feb 2023 19:48:56 +0630
Subject: [PATCH 05/25] Small doc change to avoid json parse error (#1086)
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 5ec17c82..b31a8270 100644
--- a/README.md
+++ b/README.md
@@ -90,7 +90,7 @@ You can then write this to storage.
To open a FlutterQuill editor with an existing JSON representation that you've previously stored, you can do something like this:
```dart
-var myJSON = jsonDecode(incomingJSONText);
+var myJSON = jsonDecode(r'{"insert":"hello\n"}');
_controller = QuillController(
document: Document.fromJson(myJSON),
selection: TextSelection.collapsed(offset: 0),
From e01449c9ebabddc3eb8d55afed03171e22f592ac Mon Sep 17 00:00:00 2001
From: Eric Martineau
Date: Tue, 7 Feb 2023 14:40:22 -0700
Subject: [PATCH 06/25] fix: Fixed handling of mac intents (#1089)
---
lib/src/widgets/raw_editor.dart | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/lib/src/widgets/raw_editor.dart b/lib/src/widgets/raw_editor.dart
index 1cd69e22..e5836a14 100644
--- a/lib/src/widgets/raw_editor.dart
+++ b/lib/src/widgets/raw_editor.dart
@@ -1431,7 +1431,14 @@ class RawEditorState extends EditorState
@override
void performSelector(String selectorName) {
- // TODO: implement performSelector
+ final intent = intentForMacOSSelector(selectorName);
+
+ if (intent != null) {
+ final primaryContext = primaryFocus?.context;
+ if (primaryContext != null) {
+ Actions.invoke(primaryContext, intent);
+ }
+ }
}
}
From 32a69741378acaacdbfc1f39b6e2f47815e100ae Mon Sep 17 00:00:00 2001
From: X Code
Date: Tue, 7 Feb 2023 13:49:39 -0800
Subject: [PATCH 07/25] Upgrade to 6.3.3
---
CHANGELOG.md | 3 +++
pubspec.yaml | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a7a5bd44..7c86e5f9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# [6.3.3]
+* Fixed handling of mac intents.
+
# [6.3.2]
* Added `unknownEmbedBuilder` to QuillEditor.
* Fix error style when input chinese japanese or korean.
diff --git a/pubspec.yaml b/pubspec.yaml
index cd284606..5e1787b9 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_quill
description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us)
-version: 6.3.2
+version: 6.3.3
#author: bulletjournal
homepage: https://bulletjournal.us/home/index.html
repository: https://github.com/singerdmx/flutter-quill
From 171d0b35243d5c1009fba6cdfe4ac5d3da994f2d Mon Sep 17 00:00:00 2001
From: Muhammad Faiz
Date: Fri, 10 Feb 2023 22:38:55 +0800
Subject: [PATCH 08/25] Update toolbar.i18n.dart (#1094)
---
lib/src/translations/toolbar.i18n.dart | 35 +++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/lib/src/translations/toolbar.i18n.dart b/lib/src/translations/toolbar.i18n.dart
index a5c1c651..724c0add 100644
--- a/lib/src/translations/toolbar.i18n.dart
+++ b/lib/src/translations/toolbar.i18n.dart
@@ -898,7 +898,40 @@ extension Localization on String {
'Next': 'הבא',
'Camera': 'מצלמה',
'Video': 'וידאו',
- }
+ },
+ 'ms': {
+ 'Paste a link': 'Tampal Pautan',
+ 'Ok': 'Ok',
+ 'Select Color': 'Pilih Warna',
+ 'Gallery': 'Galeri',
+ 'Link': 'Pautan',
+ 'Please first select some text to transform into a link.':
+ 'Sila pilih beberapa patah perkataan untuk diubah menjadi pautan.',
+ 'Open': 'Buka',
+ 'Copy': 'Salin',
+ 'Remove': 'Buang',
+ 'Save': 'Simpan',
+ 'Zoom': 'Zum',
+ 'Saved': 'Telah Disimpan',
+ 'Text': 'Perkataan',
+ 'What is entered is not a link': 'Apa yang diisi bukan pautan',
+ 'Resize': 'Ubah saiz',
+ 'Width': 'Lebar',
+ 'Height': 'Tinggi',
+ 'Size': 'Saiz',
+ 'Small': 'Kecil',
+ 'Large': 'Besar',
+ 'Huge': 'Amat Besar',
+ 'Clear': 'Padam',
+ 'Font': 'Fon',
+ 'Search': 'Carian',
+ 'matches': 'padanan',
+ 'showing match': 'menunjukkan padanan',
+ 'Prev': 'Sebelum',
+ 'Next': 'Seterusnya',
+ 'Camera': 'Kamera',
+ 'Video': 'Video',
+ },
};
String get i18n => localize(this, _t);
From 852c8b7f189e8e29ddcee84ea6132a583b25a2be Mon Sep 17 00:00:00 2001
From: X Code
Date: Fri, 10 Feb 2023 19:50:41 -0800
Subject: [PATCH 09/25] Update README.md
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index b31a8270..bd809b78 100644
--- a/README.md
+++ b/README.md
@@ -346,7 +346,7 @@ QuillToolbar(locale: Locale('fr'), ...)
QuillEditor(locale: Locale('fr'), ...)
```
-Currently, translations are available for these 25 locales:
+Currently, translations are available for these 26 locales:
* `Locale('en')`
* `Locale('ar')`
@@ -367,6 +367,7 @@ Currently, translations are available for these 25 locales:
* `Locale('pl')`
* `Locale('vi')`
* `Locale('id')`
+* `Locale('ms')`
* `Locale('nl')`
* `Locale('no')`
* `Locale('fa')`
From 9da4f6330d7074838deded79a80de9e89155ab7f Mon Sep 17 00:00:00 2001
From: Michael Allen
Date: Sat, 11 Feb 2023 12:34:16 -0800
Subject: [PATCH 10/25] update clipboard status prior to showing selected text
overlay (#1096)
---
lib/src/widgets/text_selection.dart | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/src/widgets/text_selection.dart b/lib/src/widgets/text_selection.dart
index dd6d6c18..74bcf55f 100644
--- a/lib/src/widgets/text_selection.dart
+++ b/lib/src/widgets/text_selection.dart
@@ -83,6 +83,11 @@ class EditorTextSelectionOverlay {
}) {
final overlay = Overlay.of(context, rootOverlay: true);
+ // Clipboard status is only checked on first instance of ClipboardStatusNotifier
+ // if state has changed after creation, but prior to our listener being created
+ // we won't know the status unless there is forced update i.e. occasionally no paste
+ this.clipboardStatus.update();
+
_toolbarController = AnimationController(
duration: const Duration(milliseconds: 150), vsync: overlay);
}
From 85fd04a6d72431d828b7de8ab089d8b4d86f638b Mon Sep 17 00:00:00 2001
From: X Code
Date: Sat, 11 Feb 2023 12:38:40 -0800
Subject: [PATCH 11/25] Upgrade to 6.3.4
---
CHANGELOG.md | 3 +++
pubspec.yaml | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7c86e5f9..1501ec48 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# [6.3.4]
+* Update clipboard status prior to showing selected text overlay.
+
# [6.3.3]
* Fixed handling of mac intents.
diff --git a/pubspec.yaml b/pubspec.yaml
index 5e1787b9..43548a05 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_quill
description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us)
-version: 6.3.3
+version: 6.3.4
#author: bulletjournal
homepage: https://bulletjournal.us/home/index.html
repository: https://github.com/singerdmx/flutter-quill
From 50f0b9961829c5a3da12f2ccdeebc202eb5c827b Mon Sep 17 00:00:00 2001
From: veselv2010 <32619716+veselv2010@users.noreply.github.com>
Date: Mon, 13 Feb 2023 18:48:56 +0300
Subject: [PATCH 12/25] feat: Ability to add custom shortcuts (#1097)
---
lib/src/widgets/editor.dart | 7 +++++++
lib/src/widgets/raw_editor.dart | 12 +++++++++++-
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/lib/src/widgets/editor.dart b/lib/src/widgets/editor.dart
index 4160e0bb..13f5ee78 100644
--- a/lib/src/widgets/editor.dart
+++ b/lib/src/widgets/editor.dart
@@ -180,6 +180,8 @@ class QuillEditor extends StatefulWidget {
this.floatingCursorDisabled = false,
this.textSelectionControls,
this.onImagePaste,
+ this.customShortcuts,
+ this.customActions,
Key? key})
: super(key: key);
@@ -394,6 +396,9 @@ class QuillEditor extends StatefulWidget {
/// Returns the url of the image if the image should be inserted.
final Future Function(Uint8List imageBytes)? onImagePaste;
+ final Map? customShortcuts;
+ final Map>? customActions;
+
@override
QuillEditorState createState() => QuillEditorState();
}
@@ -504,6 +509,8 @@ class QuillEditorState extends State
customStyleBuilder: widget.customStyleBuilder,
floatingCursorDisabled: widget.floatingCursorDisabled,
onImagePaste: widget.onImagePaste,
+ customShortcuts: widget.customShortcuts,
+ customActions: widget.customActions,
);
final editor = I18n(
diff --git a/lib/src/widgets/raw_editor.dart b/lib/src/widgets/raw_editor.dart
index e5836a14..b42c76bc 100644
--- a/lib/src/widgets/raw_editor.dart
+++ b/lib/src/widgets/raw_editor.dart
@@ -70,6 +70,8 @@ class RawEditor extends StatefulWidget {
this.minHeight,
this.maxContentWidth,
this.customStyles,
+ this.customShortcuts,
+ this.customActions,
this.expands = false,
this.autoFocus = false,
this.keyboardAppearance = Brightness.light,
@@ -227,6 +229,9 @@ class RawEditor extends StatefulWidget {
final Future Function(Uint8List imageBytes)? onImagePaste;
+ final Map? customShortcuts;
+ final Map>? customActions;
+
/// Builder function for embeddable objects.
final EmbedsBuilder embedBuilder;
final LinkActionPickerDelegate linkActionPickerDelegate;
@@ -428,9 +433,14 @@ class RawEditorState extends EditorState
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.shift,
LogicalKeyboardKey.keyL): const ApplyCheckListIntent(),
+
+ if (widget.customShortcuts != null) ...widget.customShortcuts!,
},
child: Actions(
- actions: _actions,
+ actions: {
+ ..._actions,
+ if (widget.customActions != null) ...widget.customActions!,
+ },
child: Focus(
focusNode: widget.focusNode,
onKey: _onKey,
From 97fd5d2ecafc08b52213f6543259d46cc9a6d794 Mon Sep 17 00:00:00 2001
From: X Code
Date: Mon, 13 Feb 2023 08:07:40 -0800
Subject: [PATCH 13/25] Upgrade to 6.3.5
---
CHANGELOG.md | 3 +++
pubspec.yaml | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1501ec48..439304c0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# [6.3.5]
+* Ability to add custom shortcuts.
+
# [6.3.4]
* Update clipboard status prior to showing selected text overlay.
diff --git a/pubspec.yaml b/pubspec.yaml
index 43548a05..1dc93bef 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_quill
description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us)
-version: 6.3.4
+version: 6.3.5
#author: bulletjournal
homepage: https://bulletjournal.us/home/index.html
repository: https://github.com/singerdmx/flutter-quill
From 76ea6c0e7ed694e63e41d7520c6e0e1ebdb5d7be Mon Sep 17 00:00:00 2001
From: X Code
Date: Mon, 13 Feb 2023 08:10:08 -0800
Subject: [PATCH 14/25] Fix analysis error
---
lib/src/translations/toolbar.i18n.dart | 3 ++-
lib/src/widgets/text_selection.dart | 11 +++++++----
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/lib/src/translations/toolbar.i18n.dart b/lib/src/translations/toolbar.i18n.dart
index 724c0add..fa5ea0f4 100644
--- a/lib/src/translations/toolbar.i18n.dart
+++ b/lib/src/translations/toolbar.i18n.dart
@@ -906,7 +906,8 @@ extension Localization on String {
'Gallery': 'Galeri',
'Link': 'Pautan',
'Please first select some text to transform into a link.':
- 'Sila pilih beberapa patah perkataan untuk diubah menjadi pautan.',
+ 'Sila pilih beberapa patah perkataan'
+ ' untuk diubah menjadi pautan.',
'Open': 'Buka',
'Copy': 'Salin',
'Remove': 'Buang',
diff --git a/lib/src/widgets/text_selection.dart b/lib/src/widgets/text_selection.dart
index 74bcf55f..811d3fe6 100644
--- a/lib/src/widgets/text_selection.dart
+++ b/lib/src/widgets/text_selection.dart
@@ -83,10 +83,13 @@ class EditorTextSelectionOverlay {
}) {
final overlay = Overlay.of(context, rootOverlay: true);
- // Clipboard status is only checked on first instance of ClipboardStatusNotifier
- // if state has changed after creation, but prior to our listener being created
- // we won't know the status unless there is forced update i.e. occasionally no paste
- this.clipboardStatus.update();
+ // Clipboard status is only checked on first instance of
+ // ClipboardStatusNotifier
+ // if state has changed after creation, but prior to
+ // our listener being created
+ // we won't know the status unless there is forced update
+ // i.e. occasionally no paste
+ clipboardStatus.update();
_toolbarController = AnimationController(
duration: const Duration(milliseconds: 150), vsync: overlay);
From e81ac15976bc61fa9cbd745c54ef1447cb3e5856 Mon Sep 17 00:00:00 2001
From: Adil Hanney
Date: Thu, 16 Feb 2023 04:52:24 +0000
Subject: [PATCH 15/25] Vertical toolbar (#1101)
---
CHANGELOG.md | 5 +
lib/src/widgets/toolbar.dart | 84 +++++++++-------
.../toolbar/arrow_indicated_button_list.dart | 80 ++++++++++-----
.../toolbar/select_header_style_button.dart | 97 ++++++++++---------
pubspec.yaml | 2 +-
5 files changed, 163 insertions(+), 105 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 439304c0..17eed562 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# [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.
diff --git a/lib/src/widgets/toolbar.dart b/lib/src/widgets/toolbar.dart
index 5ea2ad18..390317c2 100644
--- a/lib/src/widgets/toolbar.dart
+++ b/lib/src/widgets/toolbar.dart
@@ -45,8 +45,10 @@ const double kIconButtonFactor = 1.77;
class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
const QuillToolbar({
required this.children,
- this.toolbarHeight = 36,
+ this.axis = Axis.horizontal,
+ this.toolbarSize = 36,
this.toolbarIconAlignment = WrapAlignment.center,
+ this.toolbarIconCrossAlignment = WrapCrossAlignment.center,
this.toolbarSectionSpacing = 4,
this.multiRowsDisplay = true,
this.color,
@@ -58,9 +60,11 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
factory QuillToolbar.basic({
required QuillController controller,
+ Axis axis = Axis.horizontal,
double toolbarIconSize = kDefaultIconSize,
double toolbarSectionSpacing = 4,
WrapAlignment toolbarIconAlignment = WrapAlignment.center,
+ WrapCrossAlignment toolbarIconCrossAlignment = WrapCrossAlignment.center,
bool showDividers = true,
bool showFontFamily = true,
bool showFontSize = true,
@@ -170,10 +174,12 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
return QuillToolbar(
key: key,
+ axis: axis,
color: color,
- toolbarHeight: toolbarIconSize * 2,
+ toolbarSize: toolbarIconSize * 2,
toolbarSectionSpacing: toolbarSectionSpacing,
toolbarIconAlignment: toolbarIconAlignment,
+ toolbarIconCrossAlignment: toolbarIconCrossAlignment,
multiRowsDisplay: multiRowsDisplay,
customButtons: customButtons,
locale: locale,
@@ -334,11 +340,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
isButtonGroupShown[3] ||
isButtonGroupShown[4] ||
isButtonGroupShown[5]))
- VerticalDivider(
- indent: 12,
- endIndent: 12,
- color: Colors.grey.shade400,
- ),
+ _dividerOnAxis(axis),
if (showAlignmentButtons)
SelectAlignmentButton(
controller: controller,
@@ -365,14 +367,11 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
isButtonGroupShown[3] ||
isButtonGroupShown[4] ||
isButtonGroupShown[5]))
- VerticalDivider(
- indent: 12,
- endIndent: 12,
- color: Colors.grey.shade400,
- ),
+ _dividerOnAxis(axis),
if (showHeaderStyle)
SelectHeaderStyleButton(
controller: controller,
+ axis: axis,
iconSize: toolbarIconSize,
iconTheme: iconTheme,
afterButtonPressed: afterButtonPressed,
@@ -383,11 +382,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
(isButtonGroupShown[3] ||
isButtonGroupShown[4] ||
isButtonGroupShown[5]))
- VerticalDivider(
- indent: 12,
- endIndent: 12,
- color: Colors.grey.shade400,
- ),
+ _dividerOnAxis(axis),
if (showListNumbers)
ToggleStyleButton(
attribute: Attribute.ol,
@@ -427,11 +422,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
if (showDividers &&
isButtonGroupShown[3] &&
(isButtonGroupShown[4] || isButtonGroupShown[5]))
- VerticalDivider(
- indent: 12,
- endIndent: 12,
- color: Colors.grey.shade400,
- ),
+ _dividerOnAxis(axis),
if (showQuote)
ToggleStyleButton(
attribute: Attribute.blockQuote,
@@ -460,11 +451,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
afterButtonPressed: afterButtonPressed,
),
if (showDividers && isButtonGroupShown[4] && isButtonGroupShown[5])
- VerticalDivider(
- indent: 12,
- endIndent: 12,
- color: Colors.grey.shade400,
- ),
+ _dividerOnAxis(axis),
if (showLink)
LinkStyleButton(
controller: controller,
@@ -484,11 +471,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
),
if (customButtons.isNotEmpty)
if (showDividers)
- VerticalDivider(
- indent: 12,
- endIndent: 12,
- color: Colors.grey.shade400,
- ),
+ _dividerOnAxis(axis),
for (var customButton in customButtons)
QuillIconButton(
highlightElevation: 0,
@@ -503,10 +486,28 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
);
}
+ static Widget _dividerOnAxis(Axis axis) {
+ if (axis == Axis.horizontal) {
+ return const VerticalDivider(
+ indent: 12,
+ endIndent: 12,
+ color: Colors.grey,
+ );
+ } else {
+ return const Divider(
+ indent: 12,
+ endIndent: 12,
+ color: Colors.grey,
+ );
+ }
+ }
+
final List children;
- final double toolbarHeight;
+ final Axis axis;
+ final double toolbarSize;
final double toolbarSectionSpacing;
final WrapAlignment toolbarIconAlignment;
+ final WrapCrossAlignment toolbarIconCrossAlignment;
final bool multiRowsDisplay;
/// The color of the toolbar.
@@ -523,7 +524,9 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
final List customButtons;
@override
- Size get preferredSize => Size.fromHeight(toolbarHeight);
+ Size get preferredSize => axis == Axis.horizontal
+ ? Size.fromHeight(toolbarSize)
+ : Size.fromWidth(toolbarSize);
@override
Widget build(BuildContext context) {
@@ -531,16 +534,23 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
initialLocale: locale,
child: multiRowsDisplay
? Wrap(
+ direction: axis,
alignment: toolbarIconAlignment,
+ crossAxisAlignment: toolbarIconCrossAlignment,
runSpacing: 4,
spacing: toolbarSectionSpacing,
children: children,
)
: Container(
- constraints:
- BoxConstraints.tightFor(height: preferredSize.height),
+ constraints: BoxConstraints.tightFor(
+ height: axis == Axis.horizontal ? toolbarSize : null,
+ width: axis == Axis.vertical ? toolbarSize : null,
+ ),
color: color ?? Theme.of(context).canvasColor,
- child: ArrowIndicatedButtonList(buttons: children),
+ child: ArrowIndicatedButtonList(
+ axis: axis,
+ buttons: children,
+ ),
),
);
}
diff --git a/lib/src/widgets/toolbar/arrow_indicated_button_list.dart b/lib/src/widgets/toolbar/arrow_indicated_button_list.dart
index 1c6917a1..94e500ff 100644
--- a/lib/src/widgets/toolbar/arrow_indicated_button_list.dart
+++ b/lib/src/widgets/toolbar/arrow_indicated_button_list.dart
@@ -7,9 +7,13 @@ import 'package:flutter/material.dart';
/// The arrow indicators are automatically hidden if the list is not
/// scrollable in the direction of the respective arrow.
class ArrowIndicatedButtonList extends StatefulWidget {
- const ArrowIndicatedButtonList({required this.buttons, Key? key})
- : super(key: key);
+ const ArrowIndicatedButtonList({
+ required this.axis,
+ required this.buttons,
+ Key? key,
+ }) : super(key: key);
+ final Axis axis;
final List buttons;
@override
@@ -20,8 +24,8 @@ class ArrowIndicatedButtonList extends StatefulWidget {
class _ArrowIndicatedButtonListState extends State
with WidgetsBindingObserver {
final ScrollController _controller = ScrollController();
- bool _showLeftArrow = false;
- bool _showRightArrow = false;
+ bool _showBackwardArrow = false;
+ bool _showForwardArrow = false;
@override
void initState() {
@@ -40,13 +44,19 @@ class _ArrowIndicatedButtonListState extends State
@override
Widget build(BuildContext context) {
- return Row(
- children: [
- _buildLeftArrow(),
- _buildScrollableList(),
- _buildRightColor(),
- ],
- );
+ final children = [
+ _buildBackwardArrow(),
+ _buildScrollableList(),
+ _buildForwardArrow(),
+ ];
+
+ return widget.axis == Axis.horizontal
+ ? Row(
+ children: children,
+ )
+ : Column(
+ children: children,
+ );
}
@override
@@ -63,20 +73,29 @@ class _ArrowIndicatedButtonListState extends State
if (!mounted) return;
setState(() {
- _showLeftArrow =
+ _showBackwardArrow =
_controller.position.minScrollExtent != _controller.position.pixels;
- _showRightArrow =
+ _showForwardArrow =
_controller.position.maxScrollExtent != _controller.position.pixels;
});
}
- Widget _buildLeftArrow() {
+ Widget _buildBackwardArrow() {
+ IconData? icon;
+ if (_showBackwardArrow) {
+ if (widget.axis == Axis.horizontal) {
+ icon = Icons.arrow_left;
+ } else {
+ icon = Icons.arrow_drop_up;
+ }
+ }
+
return SizedBox(
width: 8,
child: Transform.translate(
// Move the icon a few pixels to center it
offset: const Offset(-5, 0),
- child: _showLeftArrow ? const Icon(Icons.arrow_left, size: 18) : null,
+ child: icon != null ? Icon(icon, size: 18) : null,
),
);
}
@@ -87,18 +106,24 @@ class _ArrowIndicatedButtonListState extends State
// Remove the glowing effect, as we already have the arrow indicators
behavior: _NoGlowBehavior(),
// The CustomScrollView is necessary so that the children are not
- // stretched to the height of the toolbar, https://bit.ly/3uC3bjI
+ // stretched to the height of the toolbar:
+ // https://stackoverflow.com/a/65998731/7091839
child: CustomScrollView(
- scrollDirection: Axis.horizontal,
+ scrollDirection: widget.axis,
controller: _controller,
physics: const ClampingScrollPhysics(),
slivers: [
SliverFillRemaining(
hasScrollBody: false,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: widget.buttons,
- ),
+ child: widget.axis == Axis.horizontal
+ ? Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: widget.buttons,
+ )
+ : Column(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: widget.buttons,
+ ),
)
],
),
@@ -106,13 +131,22 @@ class _ArrowIndicatedButtonListState extends State
);
}
- Widget _buildRightColor() {
+ Widget _buildForwardArrow() {
+ IconData? icon;
+ if (_showForwardArrow) {
+ if (widget.axis == Axis.horizontal) {
+ icon = Icons.arrow_right;
+ } else {
+ icon = Icons.arrow_drop_down;
+ }
+ }
+
return SizedBox(
width: 8,
child: Transform.translate(
// Move the icon a few pixels to center it
offset: const Offset(-5, 0),
- child: _showRightArrow ? const Icon(Icons.arrow_right, size: 18) : null,
+ child: icon != null ? Icon(icon, size: 18) : null,
),
);
}
diff --git a/lib/src/widgets/toolbar/select_header_style_button.dart b/lib/src/widgets/toolbar/select_header_style_button.dart
index 72192398..5e1dee9f 100644
--- a/lib/src/widgets/toolbar/select_header_style_button.dart
+++ b/lib/src/widgets/toolbar/select_header_style_button.dart
@@ -10,6 +10,7 @@ import '../toolbar.dart';
class SelectHeaderStyleButton extends StatefulWidget {
const SelectHeaderStyleButton({
required this.controller,
+ this.axis = Axis.horizontal,
this.iconSize = kDefaultIconSize,
this.iconTheme,
this.attributes = const [
@@ -23,6 +24,7 @@ class SelectHeaderStyleButton extends StatefulWidget {
}) : super(key: key);
final QuillController controller;
+ final Axis axis;
final double iconSize;
final QuillIconTheme? iconTheme;
final List attributes;
@@ -67,53 +69,60 @@ class _SelectHeaderStyleButtonState extends State {
fontSize: widget.iconSize * 0.7,
);
- return Row(
- mainAxisSize: MainAxisSize.min,
- children: widget.attributes.map((attribute) {
- final isSelected = _selectedAttribute == attribute;
- return Padding(
- // ignore: prefer_const_constructors
- padding: EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0),
- child: ConstrainedBox(
- constraints: BoxConstraints.tightFor(
- width: widget.iconSize * kIconButtonFactor,
- height: widget.iconSize * kIconButtonFactor,
- ),
- child: RawMaterialButton(
- hoverElevation: 0,
- highlightElevation: 0,
- elevation: 0,
- visualDensity: VisualDensity.compact,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(
- widget.iconTheme?.borderRadius ?? 2)),
- fillColor: isSelected
- ? (widget.iconTheme?.iconSelectedFillColor ??
- Theme.of(context).primaryColor)
- : (widget.iconTheme?.iconUnselectedFillColor ??
- theme.canvasColor),
- onPressed: () {
- final _attribute = _selectedAttribute == attribute
- ? Attribute.header
- : attribute;
- widget.controller.formatSelection(_attribute);
- widget.afterButtonPressed?.call();
- },
- child: Text(
- _valueToText[attribute] ?? '',
- style: style.copyWith(
- color: isSelected
- ? (widget.iconTheme?.iconSelectedColor ??
- theme.primaryIconTheme.color)
- : (widget.iconTheme?.iconUnselectedColor ??
- theme.iconTheme.color),
- ),
+ final children = widget.attributes.map((attribute) {
+ final isSelected = _selectedAttribute == attribute;
+ return Padding(
+ // ignore: prefer_const_constructors
+ padding: EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0),
+ child: ConstrainedBox(
+ constraints: BoxConstraints.tightFor(
+ width: widget.iconSize * kIconButtonFactor,
+ height: widget.iconSize * kIconButtonFactor,
+ ),
+ child: RawMaterialButton(
+ hoverElevation: 0,
+ highlightElevation: 0,
+ elevation: 0,
+ visualDensity: VisualDensity.compact,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(
+ widget.iconTheme?.borderRadius ?? 2)),
+ fillColor: isSelected
+ ? (widget.iconTheme?.iconSelectedFillColor ??
+ Theme.of(context).primaryColor)
+ : (widget.iconTheme?.iconUnselectedFillColor ??
+ theme.canvasColor),
+ onPressed: () {
+ final _attribute = _selectedAttribute == attribute
+ ? Attribute.header
+ : attribute;
+ widget.controller.formatSelection(_attribute);
+ widget.afterButtonPressed?.call();
+ },
+ child: Text(
+ _valueToText[attribute] ?? '',
+ style: style.copyWith(
+ color: isSelected
+ ? (widget.iconTheme?.iconSelectedColor ??
+ theme.primaryIconTheme.color)
+ : (widget.iconTheme?.iconUnselectedColor ??
+ theme.iconTheme.color),
),
),
),
- );
- }).toList(),
- );
+ ),
+ );
+ }).toList();
+
+ return widget.axis == Axis.horizontal
+ ? Row(
+ mainAxisSize: MainAxisSize.min,
+ children: children,
+ )
+ : Column(
+ mainAxisSize: MainAxisSize.min,
+ children: children,
+ );
}
void _didChangeEditingValue() {
diff --git a/pubspec.yaml b/pubspec.yaml
index 1dc93bef..951881cb 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_quill
description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us)
-version: 6.3.5
+version: 6.4.0
#author: bulletjournal
homepage: https://bulletjournal.us/home/index.html
repository: https://github.com/singerdmx/flutter-quill
From fdbebef79bff4f722583ca6593df27682f2e237e Mon Sep 17 00:00:00 2001
From: X Code
Date: Wed, 15 Feb 2023 20:55:17 -0800
Subject: [PATCH 16/25] Format code
---
lib/src/widgets/toolbar.dart | 3 +--
.../toolbar/arrow_indicated_button_list.dart | 12 ++++++------
.../toolbar/select_header_style_button.dart | 14 +++++++-------
3 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/lib/src/widgets/toolbar.dart b/lib/src/widgets/toolbar.dart
index 390317c2..58171ad1 100644
--- a/lib/src/widgets/toolbar.dart
+++ b/lib/src/widgets/toolbar.dart
@@ -470,8 +470,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
afterButtonPressed: afterButtonPressed,
),
if (customButtons.isNotEmpty)
- if (showDividers)
- _dividerOnAxis(axis),
+ if (showDividers) _dividerOnAxis(axis),
for (var customButton in customButtons)
QuillIconButton(
highlightElevation: 0,
diff --git a/lib/src/widgets/toolbar/arrow_indicated_button_list.dart b/lib/src/widgets/toolbar/arrow_indicated_button_list.dart
index 94e500ff..84f19854 100644
--- a/lib/src/widgets/toolbar/arrow_indicated_button_list.dart
+++ b/lib/src/widgets/toolbar/arrow_indicated_button_list.dart
@@ -51,12 +51,12 @@ class _ArrowIndicatedButtonListState extends State
];
return widget.axis == Axis.horizontal
- ? Row(
- children: children,
- )
- : Column(
- children: children,
- );
+ ? Row(
+ children: children,
+ )
+ : Column(
+ children: children,
+ );
}
@override
diff --git a/lib/src/widgets/toolbar/select_header_style_button.dart b/lib/src/widgets/toolbar/select_header_style_button.dart
index 5e1dee9f..f27998b8 100644
--- a/lib/src/widgets/toolbar/select_header_style_button.dart
+++ b/lib/src/widgets/toolbar/select_header_style_button.dart
@@ -69,7 +69,7 @@ class _SelectHeaderStyleButtonState extends State {
fontSize: widget.iconSize * 0.7,
);
- final children = widget.attributes.map((attribute) {
+ final children = widget.attributes.map((attribute) {
final isSelected = _selectedAttribute == attribute;
return Padding(
// ignore: prefer_const_constructors
@@ -85,13 +85,13 @@ class _SelectHeaderStyleButtonState extends State {
elevation: 0,
visualDensity: VisualDensity.compact,
shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(
- widget.iconTheme?.borderRadius ?? 2)),
+ borderRadius:
+ BorderRadius.circular(widget.iconTheme?.borderRadius ?? 2)),
fillColor: isSelected
? (widget.iconTheme?.iconSelectedFillColor ??
- Theme.of(context).primaryColor)
+ Theme.of(context).primaryColor)
: (widget.iconTheme?.iconUnselectedFillColor ??
- theme.canvasColor),
+ theme.canvasColor),
onPressed: () {
final _attribute = _selectedAttribute == attribute
? Attribute.header
@@ -104,9 +104,9 @@ class _SelectHeaderStyleButtonState extends State {
style: style.copyWith(
color: isSelected
? (widget.iconTheme?.iconSelectedColor ??
- theme.primaryIconTheme.color)
+ theme.primaryIconTheme.color)
: (widget.iconTheme?.iconUnselectedColor ??
- theme.iconTheme.color),
+ theme.iconTheme.color),
),
),
),
From c68c2bd030f6563ebcd39897d2934a13ebffacc5 Mon Sep 17 00:00:00 2001
From: sourabhguptazeil <108905944+sourabhguptazeil@users.noreply.github.com>
Date: Thu, 16 Feb 2023 21:38:49 +1300
Subject: [PATCH 17/25] Added a property to control the detect word boundary
behaviour (#1102)
---
lib/src/widgets/delegate.dart | 9 +++++++--
lib/src/widgets/editor.dart | 23 +++++++++++++++++------
lib/src/widgets/text_selection.dart | 3 +++
3 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/lib/src/widgets/delegate.dart b/lib/src/widgets/delegate.dart
index a75b64e7..a7ad9866 100644
--- a/lib/src/widgets/delegate.dart
+++ b/lib/src/widgets/delegate.dart
@@ -66,7 +66,9 @@ class EditorTextSelectionGestureDetectorBuilder {
/// Creates a [EditorTextSelectionGestureDetectorBuilder].
///
/// The [delegate] must not be null.
- EditorTextSelectionGestureDetectorBuilder({required this.delegate});
+ EditorTextSelectionGestureDetectorBuilder({
+ required this.delegate,
+ this.detectWordBoundary = true});
/// The delegate for this [EditorTextSelectionGestureDetectorBuilder].
///
@@ -83,6 +85,8 @@ class EditorTextSelectionGestureDetectorBuilder {
/// a stylus.
bool shouldShowSelectionToolbar = true;
+ bool detectWordBoundary = true;
+
/// The [State] of the [EditableText] for which the builder will provide a
/// [EditorTextSelectionGestureDetector].
@protected
@@ -354,7 +358,8 @@ class EditorTextSelectionGestureDetectorBuilder {
onDragSelectionUpdate: onDragSelectionUpdate,
onDragSelectionEnd: onDragSelectionEnd,
behavior: behavior,
- child: child,
+ detectWordBoundary: detectWordBoundary,
+ child: child
);
}
}
diff --git a/lib/src/widgets/editor.dart b/lib/src/widgets/editor.dart
index 13f5ee78..b8d007d2 100644
--- a/lib/src/widgets/editor.dart
+++ b/lib/src/widgets/editor.dart
@@ -182,6 +182,7 @@ class QuillEditor extends StatefulWidget {
this.onImagePaste,
this.customShortcuts,
this.customActions,
+ this.detectWordBoundary = true,
Key? key})
: super(key: key);
@@ -399,6 +400,8 @@ class QuillEditor extends StatefulWidget {
final Map? customShortcuts;
final Map>? customActions;
+ final bool detectWordBoundary;
+
@override
QuillEditorState createState() => QuillEditorState();
}
@@ -413,7 +416,8 @@ class QuillEditorState extends State
void initState() {
super.initState();
_selectionGestureDetectorBuilder =
- _QuillEditorSelectionGestureDetectorBuilder(this);
+ _QuillEditorSelectionGestureDetectorBuilder(this,
+ widget.detectWordBoundary);
}
@override
@@ -591,10 +595,11 @@ class QuillEditorState extends State
class _QuillEditorSelectionGestureDetectorBuilder
extends EditorTextSelectionGestureDetectorBuilder {
- _QuillEditorSelectionGestureDetectorBuilder(this._state)
- : super(delegate: _state);
+ _QuillEditorSelectionGestureDetectorBuilder(this._state, this._detectWordBoundary)
+ : super(delegate: _state, detectWordBoundary: _detectWordBoundary);
final QuillEditorState _state;
+ final bool _detectWordBoundary;
@override
void onForcePressStart(ForcePressDetails details) {
@@ -712,9 +717,15 @@ class _QuillEditorSelectionGestureDetectorBuilder
case PointerDeviceKind.unknown:
// On macOS/iOS/iPadOS a touch tap places the cursor at the edge
// of the word.
- renderEditor!
- ..selectWordEdge(SelectionChangedCause.tap)
- ..onSelectionCompleted();
+ if (_detectWordBoundary) {
+ renderEditor!
+ ..selectWordEdge(SelectionChangedCause.tap)
+ ..onSelectionCompleted();
+ } else {
+ renderEditor!
+ ..selectPosition(cause: SelectionChangedCause.tap)
+ ..onSelectionCompleted();
+ }
break;
case PointerDeviceKind.trackpad:
// TODO: Handle this case.
diff --git a/lib/src/widgets/text_selection.dart b/lib/src/widgets/text_selection.dart
index 811d3fe6..7930d468 100644
--- a/lib/src/widgets/text_selection.dart
+++ b/lib/src/widgets/text_selection.dart
@@ -714,6 +714,7 @@ class EditorTextSelectionGestureDetector extends StatefulWidget {
this.onDragSelectionUpdate,
this.onDragSelectionEnd,
this.behavior,
+ this.detectWordBoundary = true,
Key? key,
}) : super(key: key);
@@ -789,6 +790,8 @@ class EditorTextSelectionGestureDetector extends StatefulWidget {
/// Child below this widget.
final Widget child;
+ final bool detectWordBoundary;
+
@override
State createState() =>
_EditorTextSelectionGestureDetectorState();
From 83ad28bf7bddd46277e5cecb746b6827d7ca121c Mon Sep 17 00:00:00 2001
From: sourabhguptazeil <108905944+sourabhguptazeil@users.noreply.github.com>
Date: Fri, 17 Feb 2023 03:11:06 +1300
Subject: [PATCH 18/25] Added a property to control the detect word boundary
behaviour (#1103)
---
lib/src/widgets/delegate.dart | 3 ++-
lib/src/widgets/editor.dart | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/src/widgets/delegate.dart b/lib/src/widgets/delegate.dart
index a7ad9866..1de60822 100644
--- a/lib/src/widgets/delegate.dart
+++ b/lib/src/widgets/delegate.dart
@@ -341,7 +341,8 @@ class EditorTextSelectionGestureDetectorBuilder {
///
/// The [child] or its subtree should contain [EditableText].
Widget build(
- {required HitTestBehavior behavior, required Widget child, Key? key}) {
+ {required HitTestBehavior behavior, required Widget child, Key? key,
+ bool detectWordBoundary = true}) {
return EditorTextSelectionGestureDetector(
key: key,
onTapDown: onTapDown,
diff --git a/lib/src/widgets/editor.dart b/lib/src/widgets/editor.dart
index b8d007d2..fcf1e9d3 100644
--- a/lib/src/widgets/editor.dart
+++ b/lib/src/widgets/editor.dart
@@ -522,6 +522,7 @@ class QuillEditorState extends State
child: selectionEnabled
? _selectionGestureDetectorBuilder.build(
behavior: HitTestBehavior.translucent,
+ detectWordBoundary: widget.detectWordBoundary,
child: child,
)
: child,
From efd09b535ae709a31e5728571aaef8c0f60740f6 Mon Sep 17 00:00:00 2001
From: Adil Hanney
Date: Thu, 16 Feb 2023 14:12:35 +0000
Subject: [PATCH 19/25] Add `contextMenuBuilder` to `RawEditor` (#1105)
---
lib/src/widgets/editor.dart | 9 +-
lib/src/widgets/raw_editor.dart | 110 ++++++++++++++++--
...editor_state_selection_delegate_mixin.dart | 9 +-
3 files changed, 108 insertions(+), 20 deletions(-)
diff --git a/lib/src/widgets/editor.dart b/lib/src/widgets/editor.dart
index fcf1e9d3..c65898f2 100644
--- a/lib/src/widgets/editor.dart
+++ b/lib/src/widgets/editor.dart
@@ -467,12 +467,9 @@ class QuillEditorState extends State
readOnly: widget.readOnly,
placeholder: widget.placeholder,
onLaunchUrl: widget.onLaunchUrl,
- toolbarOptions: ToolbarOptions(
- copy: showSelectionToolbar,
- cut: showSelectionToolbar,
- paste: showSelectionToolbar,
- selectAll: showSelectionToolbar,
- ),
+ contextMenuBuilder: showSelectionToolbar
+ ? RawEditor.defaultContextMenuBuilder
+ : null,
showSelectionHandles: isMobile(theme.platform),
showCursor: widget.showCursor,
cursorStyle: CursorStyle(
diff --git a/lib/src/widgets/raw_editor.dart b/lib/src/widgets/raw_editor.dart
index b42c76bc..8c6c61af 100644
--- a/lib/src/widgets/raw_editor.dart
+++ b/lib/src/widgets/raw_editor.dart
@@ -57,12 +57,7 @@ class RawEditor extends StatefulWidget {
this.readOnly = false,
this.placeholder,
this.onLaunchUrl,
- this.toolbarOptions = const ToolbarOptions(
- copy: true,
- cut: true,
- paste: true,
- selectAll: true,
- ),
+ this.contextMenuBuilder = defaultContextMenuBuilder,
this.showSelectionHandles = false,
bool? showCursor,
this.textCapitalization = TextCapitalization.none,
@@ -114,11 +109,24 @@ class RawEditor extends StatefulWidget {
/// a link in the document.
final ValueChanged? onLaunchUrl;
- /// Configuration of toolbar options.
+ /// Builds the text selection toolbar when requested by the user.
+ ///
+ /// See also:
+ /// * [EditableText.contextMenuBuilder], which builds the default
+ /// text selection toolbar for [EditableText].
///
- /// By default, all options are enabled. If [readOnly] is true,
- /// paste and cut will be disabled regardless.
- final ToolbarOptions toolbarOptions;
+ /// If not provided, no context menu will be shown.
+ final QuillEditorContextMenuBuilder? contextMenuBuilder;
+
+ static Widget defaultContextMenuBuilder(
+ BuildContext context,
+ RawEditorState state,
+ ) {
+ return AdaptiveTextSelectionToolbar.buttonItems(
+ buttonItems: state.contextMenuButtonItems,
+ anchors: state.contextMenuAnchors,
+ );
+ }
/// Whether to show selection handles.
///
@@ -293,6 +301,76 @@ class RawEditorState extends EditorState
TextDirection get _textDirection => Directionality.of(context);
+ /// Returns the [ContextMenuButtonItem]s representing the buttons in this
+ /// platform's default selection menu for [RawEditor].
+ ///
+ /// Copied from [EditableTextState].
+ List get contextMenuButtonItems {
+ return EditableText.getEditableButtonItems(
+ clipboardStatus: _clipboardStatus.value,
+ onCopy: copyEnabled
+ ? () => copySelection(SelectionChangedCause.toolbar)
+ : null,
+ onCut: cutEnabled
+ ? () => cutSelection(SelectionChangedCause.toolbar)
+ : null,
+ onPaste: pasteEnabled
+ ? () => pasteText(SelectionChangedCause.toolbar)
+ : null,
+ onSelectAll: selectAllEnabled
+ ? () => selectAll(SelectionChangedCause.toolbar)
+ : null,
+ );
+ }
+
+ /// Returns the anchor points for the default context menu.
+ ///
+ /// Copied from [EditableTextState].
+ TextSelectionToolbarAnchors get contextMenuAnchors {
+ final glyphHeights = _getGlyphHeights();
+ final selection = textEditingValue.selection;
+ final points = renderEditor.getEndpointsForSelection(selection);
+ return TextSelectionToolbarAnchors.fromSelection(
+ renderBox: renderEditor,
+ startGlyphHeight: glyphHeights.item1,
+ endGlyphHeight: glyphHeights.item2,
+ selectionEndpoints: points,
+ );
+ }
+
+ /// Gets the line heights at the start and end of the selection for the given
+ /// [RawEditorState].
+ ///
+ /// Copied from [EditableTextState].
+ Tuple2 _getGlyphHeights() {
+ final selection = textEditingValue.selection;
+
+ // Only calculate handle rects if the text in the previous frame
+ // is the same as the text in the current frame. This is done because
+ // widget.renderObject contains the renderEditable from the previous frame.
+ // If the text changed between the current and previous frames then
+ // widget.renderObject.getRectForComposingRange might fail. In cases where
+ // the current frame is different from the previous we fall back to
+ // renderObject.preferredLineHeight.
+ final prevText = renderEditor.document.toPlainText();
+ final currText = textEditingValue.text;
+ if (prevText != currText || !selection.isValid || selection.isCollapsed) {
+ return Tuple2(
+ renderEditor.preferredLineHeight(selection.base),
+ renderEditor.preferredLineHeight(selection.base),
+ );
+ }
+
+ final startCharacterRect =
+ renderEditor.getLocalRectForCaret(selection.base);
+ final endCharacterRect =
+ renderEditor.getLocalRectForCaret(selection.extent);
+ return Tuple2(
+ startCharacterRect.height,
+ endCharacterRect.height,
+ );
+ }
+
@override
Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context));
@@ -2333,3 +2411,15 @@ class _ApplyCheckListAction extends Action {
@override
bool get isActionEnabled => true;
}
+
+/// Signature for a widget builder that builds a context menu for the given
+/// [RawEditorState].
+///
+/// See also:
+///
+/// * [EditableTextContextMenuBuilder], which performs the same role for
+/// [EditableText]
+typedef QuillEditorContextMenuBuilder = Widget Function(
+ BuildContext context,
+ RawEditorState rawEditorState,
+);
diff --git a/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart b/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart
index 8b494dd1..98cfb407 100644
--- a/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart
+++ b/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart
@@ -150,14 +150,15 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState
}
@override
- bool get cutEnabled => widget.toolbarOptions.cut && !widget.readOnly;
+ bool get cutEnabled => widget.contextMenuBuilder != null && !widget.readOnly;
@override
- bool get copyEnabled => widget.toolbarOptions.copy;
+ bool get copyEnabled => widget.contextMenuBuilder != null;
@override
- bool get pasteEnabled => widget.toolbarOptions.paste && !widget.readOnly;
+ bool get pasteEnabled => widget.contextMenuBuilder != null
+ && !widget.readOnly;
@override
- bool get selectAllEnabled => widget.toolbarOptions.selectAll;
+ bool get selectAllEnabled => widget.contextMenuBuilder != null;
}
From 06d62d61bbbb08acda70a727944d9e1a0f821765 Mon Sep 17 00:00:00 2001
From: X Code
Date: Thu, 16 Feb 2023 08:04:07 -0800
Subject: [PATCH 20/25] Upgrade to 6.4.1
---
CHANGELOG.md | 3 ++
lib/src/widgets/delegate.dart | 47 ++++++++++---------
lib/src/widgets/editor.dart | 12 ++---
lib/src/widgets/raw_editor.dart | 10 ++--
...editor_state_selection_delegate_mixin.dart | 4 +-
pubspec.yaml | 2 +-
6 files changed, 40 insertions(+), 38 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 17eed562..637cfbd3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# [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.
diff --git a/lib/src/widgets/delegate.dart b/lib/src/widgets/delegate.dart
index 1de60822..ce8e65a3 100644
--- a/lib/src/widgets/delegate.dart
+++ b/lib/src/widgets/delegate.dart
@@ -66,9 +66,8 @@ class EditorTextSelectionGestureDetectorBuilder {
/// Creates a [EditorTextSelectionGestureDetectorBuilder].
///
/// The [delegate] must not be null.
- EditorTextSelectionGestureDetectorBuilder({
- required this.delegate,
- this.detectWordBoundary = true});
+ EditorTextSelectionGestureDetectorBuilder(
+ {required this.delegate, this.detectWordBoundary = true});
/// The delegate for this [EditorTextSelectionGestureDetectorBuilder].
///
@@ -341,26 +340,28 @@ class EditorTextSelectionGestureDetectorBuilder {
///
/// The [child] or its subtree should contain [EditableText].
Widget build(
- {required HitTestBehavior behavior, required Widget child, Key? key,
- bool detectWordBoundary = true}) {
+ {required HitTestBehavior behavior,
+ required Widget child,
+ Key? key,
+ bool detectWordBoundary = true}) {
return EditorTextSelectionGestureDetector(
- key: key,
- onTapDown: onTapDown,
- onForcePressStart: delegate.forcePressEnabled ? onForcePressStart : null,
- onForcePressEnd: delegate.forcePressEnabled ? onForcePressEnd : null,
- onSingleTapUp: onSingleTapUp,
- onSingleTapCancel: onSingleTapCancel,
- onSingleLongTapStart: onSingleLongTapStart,
- onSingleLongTapMoveUpdate: onSingleLongTapMoveUpdate,
- onSingleLongTapEnd: onSingleLongTapEnd,
- onDoubleTapDown: onDoubleTapDown,
- onSecondarySingleTapUp: onSecondarySingleTapUp,
- onDragSelectionStart: onDragSelectionStart,
- onDragSelectionUpdate: onDragSelectionUpdate,
- onDragSelectionEnd: onDragSelectionEnd,
- behavior: behavior,
- detectWordBoundary: detectWordBoundary,
- child: child
- );
+ key: key,
+ onTapDown: onTapDown,
+ onForcePressStart:
+ delegate.forcePressEnabled ? onForcePressStart : null,
+ onForcePressEnd: delegate.forcePressEnabled ? onForcePressEnd : null,
+ onSingleTapUp: onSingleTapUp,
+ onSingleTapCancel: onSingleTapCancel,
+ onSingleLongTapStart: onSingleLongTapStart,
+ onSingleLongTapMoveUpdate: onSingleLongTapMoveUpdate,
+ onSingleLongTapEnd: onSingleLongTapEnd,
+ onDoubleTapDown: onDoubleTapDown,
+ onSecondarySingleTapUp: onSecondarySingleTapUp,
+ onDragSelectionStart: onDragSelectionStart,
+ onDragSelectionUpdate: onDragSelectionUpdate,
+ onDragSelectionEnd: onDragSelectionEnd,
+ behavior: behavior,
+ detectWordBoundary: detectWordBoundary,
+ child: child);
}
}
diff --git a/lib/src/widgets/editor.dart b/lib/src/widgets/editor.dart
index c65898f2..7c8d7c10 100644
--- a/lib/src/widgets/editor.dart
+++ b/lib/src/widgets/editor.dart
@@ -416,8 +416,8 @@ class QuillEditorState extends State
void initState() {
super.initState();
_selectionGestureDetectorBuilder =
- _QuillEditorSelectionGestureDetectorBuilder(this,
- widget.detectWordBoundary);
+ _QuillEditorSelectionGestureDetectorBuilder(
+ this, widget.detectWordBoundary);
}
@override
@@ -467,9 +467,8 @@ class QuillEditorState extends State
readOnly: widget.readOnly,
placeholder: widget.placeholder,
onLaunchUrl: widget.onLaunchUrl,
- contextMenuBuilder: showSelectionToolbar
- ? RawEditor.defaultContextMenuBuilder
- : null,
+ contextMenuBuilder:
+ showSelectionToolbar ? RawEditor.defaultContextMenuBuilder : null,
showSelectionHandles: isMobile(theme.platform),
showCursor: widget.showCursor,
cursorStyle: CursorStyle(
@@ -593,7 +592,8 @@ class QuillEditorState extends State
class _QuillEditorSelectionGestureDetectorBuilder
extends EditorTextSelectionGestureDetectorBuilder {
- _QuillEditorSelectionGestureDetectorBuilder(this._state, this._detectWordBoundary)
+ _QuillEditorSelectionGestureDetectorBuilder(
+ this._state, this._detectWordBoundary)
: super(delegate: _state, detectWordBoundary: _detectWordBoundary);
final QuillEditorState _state;
diff --git a/lib/src/widgets/raw_editor.dart b/lib/src/widgets/raw_editor.dart
index 8c6c61af..d6496ee6 100644
--- a/lib/src/widgets/raw_editor.dart
+++ b/lib/src/widgets/raw_editor.dart
@@ -311,12 +311,10 @@ class RawEditorState extends EditorState
onCopy: copyEnabled
? () => copySelection(SelectionChangedCause.toolbar)
: null,
- onCut: cutEnabled
- ? () => cutSelection(SelectionChangedCause.toolbar)
- : null,
- onPaste: pasteEnabled
- ? () => pasteText(SelectionChangedCause.toolbar)
- : null,
+ onCut:
+ cutEnabled ? () => cutSelection(SelectionChangedCause.toolbar) : null,
+ onPaste:
+ pasteEnabled ? () => pasteText(SelectionChangedCause.toolbar) : null,
onSelectAll: selectAllEnabled
? () => selectAll(SelectionChangedCause.toolbar)
: null,
diff --git a/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart b/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart
index 98cfb407..5da7cef2 100644
--- a/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart
+++ b/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart
@@ -156,8 +156,8 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState
bool get copyEnabled => widget.contextMenuBuilder != null;
@override
- bool get pasteEnabled => widget.contextMenuBuilder != null
- && !widget.readOnly;
+ bool get pasteEnabled =>
+ widget.contextMenuBuilder != null && !widget.readOnly;
@override
bool get selectAllEnabled => widget.contextMenuBuilder != null;
diff --git a/pubspec.yaml b/pubspec.yaml
index 951881cb..6300860a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_quill
description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us)
-version: 6.4.0
+version: 6.4.1
#author: bulletjournal
homepage: https://bulletjournal.us/home/index.html
repository: https://github.com/singerdmx/flutter-quill
From 967af17a756d52e0abf17003f32b091bc229ec27 Mon Sep 17 00:00:00 2001
From: Adil Hanney
Date: Fri, 17 Feb 2023 01:32:29 +0000
Subject: [PATCH 21/25] Replace `buildToolbar` with `contextMenuBuilder`
(#1106)
---
lib/src/widgets/raw_editor.dart | 4 +-
lib/src/widgets/text_selection.dart | 84 ++++-------------------------
2 files changed, 13 insertions(+), 75 deletions(-)
diff --git a/lib/src/widgets/raw_editor.dart b/lib/src/widgets/raw_editor.dart
index d6496ee6..22738b8f 100644
--- a/lib/src/widgets/raw_editor.dart
+++ b/lib/src/widgets/raw_editor.dart
@@ -1050,13 +1050,15 @@ class RawEditorState extends EditorState
value: textEditingValue,
context: context,
debugRequiredFor: widget,
- toolbarLayerLink: _toolbarLayerLink,
startHandleLayerLink: _startHandleLayerLink,
endHandleLayerLink: _endHandleLayerLink,
renderObject: renderEditor,
selectionCtrls: widget.selectionCtrls,
selectionDelegate: this,
clipboardStatus: _clipboardStatus,
+ contextMenuBuilder: widget.contextMenuBuilder == null
+ ? null
+ : (context) => widget.contextMenuBuilder!(context, this),
);
_selectionOverlay!.handlesVisible = _shouldShowSelectionHandles();
_selectionOverlay!.showHandles();
diff --git a/lib/src/widgets/text_selection.dart b/lib/src/widgets/text_selection.dart
index 7930d468..ad1398e0 100644
--- a/lib/src/widgets/text_selection.dart
+++ b/lib/src/widgets/text_selection.dart
@@ -69,7 +69,6 @@ class EditorTextSelectionOverlay {
EditorTextSelectionOverlay({
required this.value,
required this.context,
- required this.toolbarLayerLink,
required this.startHandleLayerLink,
required this.endHandleLayerLink,
required this.renderObject,
@@ -77,12 +76,11 @@ class EditorTextSelectionOverlay {
required this.selectionCtrls,
required this.selectionDelegate,
required this.clipboardStatus,
+ required this.contextMenuBuilder,
this.onSelectionHandleTapped,
this.dragStartBehavior = DragStartBehavior.start,
this.handlesVisible = false,
}) {
- final overlay = Overlay.of(context, rootOverlay: true);
-
// Clipboard status is only checked on first instance of
// ClipboardStatusNotifier
// if state has changed after creation, but prior to
@@ -90,9 +88,6 @@ class EditorTextSelectionOverlay {
// we won't know the status unless there is forced update
// i.e. occasionally no paste
clipboardStatus.update();
-
- _toolbarController = AnimationController(
- duration: const Duration(milliseconds: 150), vsync: overlay);
}
TextEditingValue value;
@@ -122,10 +117,6 @@ class EditorTextSelectionOverlay {
/// Debugging information for explaining why the [Overlay] is required.
final Widget debugRequiredFor;
- /// The object supplied to the [CompositedTransformTarget] that wraps the text
- /// field.
- final LayerLink toolbarLayerLink;
-
/// The objects supplied to the [CompositedTransformTarget] that wraps the
/// location of start selection handle.
final LayerLink startHandleLayerLink;
@@ -144,6 +135,11 @@ class EditorTextSelectionOverlay {
/// text field.
final TextSelectionDelegate selectionDelegate;
+ /// {@macro flutter.widgets.EditableText.contextMenuBuilder}
+ ///
+ /// If not provided, no context menu will be built.
+ final WidgetBuilder? contextMenuBuilder;
+
/// Determines the way that drag start behavior is handled.
///
/// If set to [DragStartBehavior.start], handle drag behavior will
@@ -177,7 +173,6 @@ class EditorTextSelectionOverlay {
/// Useful because the actual value of the clipboard can only be checked
/// asynchronously (see [Clipboard.getData]).
final ClipboardStatusNotifier clipboardStatus;
- late AnimationController _toolbarController;
/// A pair of handles. If this is non-null, there are always 2, though the
/// second is hidden when the selection is collapsed.
@@ -188,8 +183,6 @@ class EditorTextSelectionOverlay {
TextSelection get _selection => value.selection;
- Animation get _toolbarOpacity => _toolbarController.view;
-
void setHandlesVisible(bool visible) {
if (handlesVisible == visible) {
return;
@@ -220,7 +213,6 @@ class EditorTextSelectionOverlay {
/// To hide the whole overlay, see [hide].
void hideToolbar() {
assert(toolbar != null);
- _toolbarController.stop();
toolbar!.remove();
toolbar = null;
}
@@ -228,10 +220,12 @@ class EditorTextSelectionOverlay {
/// Shows the toolbar by inserting it into the [context]'s overlay.
void showToolbar() {
assert(toolbar == null);
- toolbar = OverlayEntry(builder: _buildToolbar);
+ if (contextMenuBuilder == null) return;
+ toolbar = OverlayEntry(builder: (context) {
+ return contextMenuBuilder!(context);
+ });
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor)
.insert(toolbar!);
- _toolbarController.forward(from: 0);
// make sure handles are visible as well
if (_handles == null) {
@@ -319,63 +313,6 @@ class EditorTextSelectionOverlay {
..bringIntoView(textPosition);
}
- Widget _buildToolbar(BuildContext context) {
- // Find the horizontal midpoint, just above the selected text.
- List endpoints;
-
- try {
- // building with an invalid selection with throw an exception
- // This happens where the selection has changed, but the toolbar
- // hasn't been dismissed yet.
- endpoints = renderObject.getEndpointsForSelection(_selection);
- } catch (_) {
- return Container();
- }
-
- final editingRegion = Rect.fromPoints(
- renderObject.localToGlobal(Offset.zero),
- renderObject.localToGlobal(renderObject.size.bottomRight(Offset.zero)),
- );
-
- final baseLineHeight = renderObject.preferredLineHeight(_selection.base);
- final extentLineHeight =
- renderObject.preferredLineHeight(_selection.extent);
- final smallestLineHeight = math.min(baseLineHeight, extentLineHeight);
- final isMultiline = endpoints.last.point.dy - endpoints.first.point.dy >
- smallestLineHeight / 2;
-
- // If the selected text spans more than 1 line,
- // horizontally center the toolbar.
- // Derived from both iOS and Android.
- final midX = isMultiline
- ? editingRegion.width / 2
- : (endpoints.first.point.dx + endpoints.last.point.dx) / 2;
-
- final midpoint = Offset(
- midX,
- // The y-coordinate won't be made use of most likely.
- endpoints[0].point.dy - baseLineHeight,
- );
-
- return FadeTransition(
- opacity: _toolbarOpacity,
- child: CompositedTransformFollower(
- link: toolbarLayerLink,
- showWhenUnlinked: false,
- offset: -editingRegion.topLeft,
- child: selectionCtrls.buildToolbar(
- context,
- editingRegion,
- baseLineHeight,
- midpoint,
- endpoints,
- selectionDelegate,
- clipboardStatus,
- null),
- ),
- );
- }
-
void markNeedsBuild([Duration? duration]) {
if (_handles != null) {
_handles![0].markNeedsBuild();
@@ -399,7 +336,6 @@ class EditorTextSelectionOverlay {
/// Final cleanup.
void dispose() {
hide();
- _toolbarController.dispose();
}
/// Builds the handles by inserting them into the [context]'s overlay.
From e3b664e319325fc9889a78457bddd37fd805254e Mon Sep 17 00:00:00 2001
From: X Code
Date: Thu, 16 Feb 2023 19:38:16 -0800
Subject: [PATCH 22/25] Upgrade to 6.4.2
---
CHANGELOG.md | 3 +++
pubspec.yaml | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 637cfbd3..cf178f88 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# [6.4.2]
+* Replace `buildToolbar` with `contextMenuBuilder`.
+
# [6.4.1]
* Control the detect word boundary behaviour.
diff --git a/pubspec.yaml b/pubspec.yaml
index 6300860a..9542532c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_quill
description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us)
-version: 6.4.1
+version: 6.4.2
#author: bulletjournal
homepage: https://bulletjournal.us/home/index.html
repository: https://github.com/singerdmx/flutter-quill
From ab5690a6d7a159e32469402cb9abe7b3bed5e6ce Mon Sep 17 00:00:00 2001
From: mark8044 <87546778+mark8044@users.noreply.github.com>
Date: Thu, 16 Feb 2023 20:31:02 -0800
Subject: [PATCH 23/25] Update some dependencies (#1107)
* Update pubspec.yaml
* Update pubspec.yaml
* Update pubspec.yaml
* Update CHANGELOG.md
---
CHANGELOG.md | 3 +++
pubspec.yaml | 18 +++++++++---------
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cf178f88..647476ba 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# [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`.
diff --git a/pubspec.yaml b/pubspec.yaml
index 9542532c..dda8c4ee 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_quill
description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us)
-version: 6.4.2
+version: 6.4.3
#author: bulletjournal
homepage: https://bulletjournal.us/home/index.html
repository: https://github.com/singerdmx/flutter-quill
@@ -12,17 +12,17 @@ environment:
dependencies:
flutter:
sdk: flutter
- collection: ^1.16.0
+ collection: ^1.17.0
flutter_colorpicker: ^1.0.3
- flutter_keyboard_visibility: ^5.2.0
- quiver: ^3.1.0
- tuple: ^2.0.0
- url_launcher: ^6.1.2
+ flutter_keyboard_visibility: ^5.4.0
+ quiver: ^3.2.1
+ tuple: ^2.0.1
+ url_launcher: ^6.1.9
pedantic: ^1.11.1
- characters: ^1.2.0
+ characters: ^1.2.1
diff_match_patch: ^0.4.1
- i18n_extension: ^6.0.0
- device_info_plus: ^8.0.0
+ i18n_extension: ^7.0.0
+ device_info_plus: ^8.1.0
platform: ^3.1.0
pasteboard: ^0.2.0
From 70fb6017965bc687308d5ecd63a6a636fbb19833 Mon Sep 17 00:00:00 2001
From: Adil Hanney
Date: Sun, 19 Feb 2023 14:31:18 +0000
Subject: [PATCH 24/25] Fix some MissingPluginExceptions in tests (#1108)
---
lib/src/utils/platform.dart | 4 ++++
lib/src/widgets/raw_editor.dart | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/lib/src/utils/platform.dart b/lib/src/utils/platform.dart
index 27d183aa..96cb866b 100644
--- a/lib/src/utils/platform.dart
+++ b/lib/src/utils/platform.dart
@@ -26,6 +26,10 @@ bool isAppleOS([TargetPlatform? targetPlatform]) {
}
Future isIOSSimulator() async {
+ if (!isAppleOS()) {
+ return false;
+ }
+
final deviceInfo = DeviceInfoPlugin();
final osInfo = await deviceInfo.deviceInfo;
diff --git a/lib/src/widgets/raw_editor.dart b/lib/src/widgets/raw_editor.dart
index 22738b8f..75a4203c 100644
--- a/lib/src/widgets/raw_editor.dart
+++ b/lib/src/widgets/raw_editor.dart
@@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:convert';
+import 'dart:io';
import 'dart:math' as math;
// ignore: unnecessary_import
import 'dart:typed_data';
@@ -844,6 +845,9 @@ class RawEditorState extends EditorState
if (isKeyboardOS()) {
_keyboardVisible = true;
+ } else if (!kIsWeb && Platform.environment.containsKey('FLUTTER_TEST')) {
+ // treat tests like a keyboard OS
+ _keyboardVisible = true;
} else {
// treat iOS Simulator like a keyboard OS
isIOSSimulator().then((isIosSimulator) {
From df8056c5b26a86e2eef00c7fb8989eef74269abb Mon Sep 17 00:00:00 2001
From: Adil Hanney
Date: Mon, 20 Feb 2023 16:15:09 +0000
Subject: [PATCH 25/25] Upgrade to 6.4.4 (#1109)
---
CHANGELOG.md | 3 +++
pubspec.yaml | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 647476ba..8e8c2dee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# [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)
diff --git a/pubspec.yaml b/pubspec.yaml
index dda8c4ee..06f8fa10 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_quill
description: A rich text editor supporting mobile and web (Demo App @ bulletjournal.us)
-version: 6.4.3
+version: 6.4.4
#author: bulletjournal
homepage: https://bulletjournal.us/home/index.html
repository: https://github.com/singerdmx/flutter-quill