From 7fbda46988ceb4ea35fb2677c58def1d1484e9b1 Mon Sep 17 00:00:00 2001 From: X Code Date: Mon, 31 Jan 2022 13:55:24 -0800 Subject: [PATCH] Copy image with its style --- lib/src/models/documents/nodes/line.dart | 5 +++- lib/src/utils/string.dart | 3 +-- lib/src/widgets/controller.dart | 9 ++++--- .../widgets/embeds/default_embed_builder.dart | 25 ++++++++++--------- lib/src/widgets/raw_editor.dart | 11 +++++--- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/lib/src/models/documents/nodes/line.dart b/lib/src/models/documents/nodes/line.dart index 83c07324..4ba74b20 100644 --- a/lib/src/models/documents/nodes/line.dart +++ b/lib/src/models/documents/nodes/line.dart @@ -129,7 +129,10 @@ class Line extends Container { final isLineFormat = (index + local == thisLength) && local == 1; if (isLineFormat) { - assert(style.values.every((attr) => attr.scope == AttributeScope.BLOCK), + assert( + style.values.every((attr) => + attr.scope == AttributeScope.BLOCK || + attr.scope == AttributeScope.IGNORE), 'It is not allowed to apply inline attributes to line itself.'); _format(style); } else { diff --git a/lib/src/utils/string.dart b/lib/src/utils/string.dart index d848b11e..3831c601 100644 --- a/lib/src/utils/string.dart +++ b/lib/src/utils/string.dart @@ -17,8 +17,7 @@ Map parseKeyValuePairs(String s, Set targetKeys) { return result; } -String replaceStyleString(String? s, double width, double height) { - s ??= ''; +String replaceStyleString(String s, double width, double height) { final result = {}; final pairs = s.split(';'); for (final pair in pairs) { diff --git a/lib/src/widgets/controller.dart b/lib/src/widgets/controller.dart index e03d8978..8d52e730 100644 --- a/lib/src/widgets/controller.dart +++ b/lib/src/widgets/controller.dart @@ -334,12 +334,13 @@ class QuillController extends ChangeNotifier { return document.querySegmentLeafNode(offset).item2; } - /// Clipboard for image url - String? _copiedImageUrl; + /// Clipboard for image url and its corresponding style + /// item1 is url and item2 is style string + Tuple2? _copiedImageUrl; - String? getCopiedImageUrl() => _copiedImageUrl; + Tuple2? get copiedImageUrl => _copiedImageUrl; - set copiedImageUrl(String? value) { + set copiedImageUrl(Tuple2? value) { _copiedImageUrl = value; Clipboard.setData(const ClipboardData(text: '')); } diff --git a/lib/src/widgets/embeds/default_embed_builder.dart b/lib/src/widgets/embeds/default_embed_builder.dart index 2d219b91..7dc7b84a 100644 --- a/lib/src/widgets/embeds/default_embed_builder.dart +++ b/lib/src/widgets/embeds/default_embed_builder.dart @@ -69,21 +69,11 @@ Widget defaultEmbedBuilder(BuildContext context, QuillController controller, context: context, builder: (context) { final _screenSize = MediaQuery.of(context).size; - final _style = controller - .getAllSelectionStyles() - .firstWhere( - (s) => s.attributes - .containsKey(Attribute.style.key), - orElse: () => Style()); - return ImageResizer( onImageResize: (w, h) { final res = _getImageNode(controller); final attr = replaceStyleString( - _style.attributes[Attribute.style.key] - ?.value, - w, - h); + _getImageStyleString(controller), w, h); controller.formatText( res.item1, 1, StyleAttribute(attr)); }, @@ -101,7 +91,8 @@ Widget defaultEmbedBuilder(BuildContext context, QuillController controller, onPressed: () { final imageNode = _getImageNode(controller).item2; final imageUrl = imageNode.value.data; - controller.copiedImageUrl = imageUrl; + controller.copiedImageUrl = + Tuple2(imageUrl, _getImageStyleString(controller)); Navigator.pop(context); }, ); @@ -151,6 +142,16 @@ Widget defaultEmbedBuilder(BuildContext context, QuillController controller, } } +String _getImageStyleString(QuillController controller) { + final String? s = controller + .getAllSelectionStyles() + .firstWhere((s) => s.attributes.containsKey(Attribute.style.key), + orElse: () => Style()) + .attributes[Attribute.style.key] + ?.value; + return s ?? ''; +} + Tuple2 _getImageNode(QuillController controller) { var offset = controller.selection.start; var imageNode = controller.queryNode(offset); diff --git a/lib/src/widgets/raw_editor.dart b/lib/src/widgets/raw_editor.dart index f77bda64..d4b26f71 100644 --- a/lib/src/widgets/raw_editor.dart +++ b/lib/src/widgets/raw_editor.dart @@ -920,11 +920,16 @@ class RawEditorState extends EditorState @override Future pasteText(SelectionChangedCause cause) async { - if (widget.controller.getCopiedImageUrl() != null) { + if (widget.controller.copiedImageUrl != null) { final index = textEditingValue.selection.baseOffset; final length = textEditingValue.selection.extentOffset - index; - widget.controller.replaceText(index, length, - BlockEmbed.image(widget.controller.getCopiedImageUrl()!), null); + final copied = widget.controller.copiedImageUrl!; + widget.controller + .replaceText(index, length, BlockEmbed.image(copied.item1), null); + if (copied.item2.isNotEmpty) { + widget.controller + .formatText(index + 1, 1, StyleAttribute(copied.item2)); + } widget.controller.copiedImageUrl = null; await Clipboard.setData(const ClipboardData(text: '')); return;