diff --git a/example/lib/universal_ui/universal_ui.dart b/example/lib/universal_ui/universal_ui.dart index 55f54a7e..7d04f492 100644 --- a/example/lib/universal_ui/universal_ui.dart +++ b/example/lib/universal_ui/universal_ui.dart @@ -28,7 +28,7 @@ var ui = UniversalUI(); Widget defaultEmbedBuilderWeb(BuildContext context, Embed node, bool readOnly) { switch (node.value.type) { case 'image': - final imageUrl = node.value.data; + final String imageUrl = node.value.data; final size = MediaQuery.of(context).size; UniversalUI().platformViewRegistry.registerViewFactory( imageUrl, (viewId) => html.ImageElement()..src = imageUrl); diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 1d7dc86f..8b0a76ee 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -2,7 +2,7 @@ library flutter_quill; export 'src/models/documents/attribute.dart'; export 'src/models/documents/document.dart'; -export 'src/models/documents/nodes/embeddable.dart'; +export 'src/models/documents/nodes/embed.dart'; export 'src/models/documents/nodes/leaf.dart'; export 'src/models/quill_delta.dart'; export 'src/models/themes/quill_dialog_theme.dart'; diff --git a/lib/src/models/documents/document.dart b/lib/src/models/documents/document.dart index 424dfd67..9e6ce6b7 100644 --- a/lib/src/models/documents/document.dart +++ b/lib/src/models/documents/document.dart @@ -8,7 +8,7 @@ import 'attribute.dart'; import 'history.dart'; import 'nodes/block.dart'; import 'nodes/container.dart'; -import 'nodes/embeddable.dart'; +import 'nodes/embed.dart'; import 'nodes/line.dart'; import 'nodes/node.dart'; import 'style.dart'; @@ -230,7 +230,7 @@ class Document { if (data is Embeddable) { return data; } - return Embeddable.fromJson(data as Map); + return Embeddable.fromJson(data as Map); } void close() { diff --git a/lib/src/models/documents/nodes/embed.dart b/lib/src/models/documents/nodes/embed.dart new file mode 100644 index 00000000..c3d57f02 --- /dev/null +++ b/lib/src/models/documents/nodes/embed.dart @@ -0,0 +1,42 @@ +/// An object which can be embedded into a Quill document. +/// +/// See also: +/// +/// * [BlockEmbed] which represents a block embed. +class Embeddable { + const Embeddable(this.type, this.data); + + /// The type of this object. + final String type; + + /// The data payload of this object. + final dynamic data; + + Map toJson() { + final m = {type: data}; + return m; + } + + static Embeddable fromJson(Map json) { + final m = Map.from(json); + assert(m.length == 1, 'Embeddable map must only have one key'); + + return BlockEmbed(m.keys.first, m.values.first); + } +} + +/// An object which occupies an entire line in a document and cannot co-exist +/// inline with regular text. +/// +/// There are two built-in embed types supported by Quill documents, however +/// the document model itself does not make any assumptions about the types +/// of embedded objects and allows users to define their own types. +class BlockEmbed extends Embeddable { + const BlockEmbed(String type, String data) : super(type, data); + + static const String imageType = 'image'; + static BlockEmbed image(String imageUrl) => BlockEmbed(imageType, imageUrl); + + static const String videoType = 'video'; + static BlockEmbed video(String videoUrl) => BlockEmbed(videoType, videoUrl); +} diff --git a/lib/src/models/documents/nodes/embeddable.dart b/lib/src/models/documents/nodes/embeddable.dart deleted file mode 100644 index 8389bfbd..00000000 --- a/lib/src/models/documents/nodes/embeddable.dart +++ /dev/null @@ -1,28 +0,0 @@ -/// An object which can be embedded into a Quill document. -class Embeddable { - const Embeddable(this.type, this.data); - - /// The type of this object. - final String type; - - /// The data payload of this object. - final String data; - - Map toJson() { - final m = {type: data}; - return m; - } - - static Embeddable fromJson(Map json) { - final m = Map.from(json); - assert(m.length == 1, 'Embeddable map must only have one key'); - - return Embeddable(m.keys.single, m.values.single); - } - - static const String imageType = 'image'; - static Embeddable image(String imageUrl) => Embeddable(imageType, imageUrl); - - static const String videoType = 'video'; - static Embeddable video(String videoUrl) => Embeddable(videoType, videoUrl); -} diff --git a/lib/src/models/documents/nodes/leaf.dart b/lib/src/models/documents/nodes/leaf.dart index f2ccf75c..3895fd62 100644 --- a/lib/src/models/documents/nodes/leaf.dart +++ b/lib/src/models/documents/nodes/leaf.dart @@ -2,7 +2,7 @@ import 'dart:math' as math; import '../../quill_delta.dart'; import '../style.dart'; -import 'embeddable.dart'; +import 'embed.dart'; import 'line.dart'; import 'node.dart'; diff --git a/lib/src/models/documents/nodes/line.dart b/lib/src/models/documents/nodes/line.dart index cd951173..2476192a 100644 --- a/lib/src/models/documents/nodes/line.dart +++ b/lib/src/models/documents/nodes/line.dart @@ -7,7 +7,7 @@ import '../attribute.dart'; import '../style.dart'; import 'block.dart'; import 'container.dart'; -import 'embeddable.dart'; +import 'embed.dart'; import 'leaf.dart'; import 'node.dart'; diff --git a/lib/src/widgets/controller.dart b/lib/src/widgets/controller.dart index 8df60cb5..ed4a5a42 100644 --- a/lib/src/widgets/controller.dart +++ b/lib/src/widgets/controller.dart @@ -5,7 +5,7 @@ import 'package:tuple/tuple.dart'; import '../models/documents/attribute.dart'; import '../models/documents/document.dart'; -import '../models/documents/nodes/embeddable.dart'; +import '../models/documents/nodes/embed.dart'; import '../models/documents/style.dart'; import '../models/quill_delta.dart'; import '../utils/delta.dart'; diff --git a/lib/src/widgets/toolbar/image_button.dart b/lib/src/widgets/toolbar/image_button.dart index 6f79f486..5edd58dd 100644 --- a/lib/src/widgets/toolbar/image_button.dart +++ b/lib/src/widgets/toolbar/image_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; -import '../../models/documents/nodes/embeddable.dart'; +import '../../models/documents/nodes/embed.dart'; import '../../models/themes/quill_dialog_theme.dart'; import '../../models/themes/quill_icon_theme.dart'; import '../controller.dart'; @@ -98,7 +98,7 @@ class ImageButton extends StatelessWidget { final index = controller.selection.baseOffset; final length = controller.selection.extentOffset - index; - controller.replaceText(index, length, Embeddable.image(value), null); + controller.replaceText(index, length, BlockEmbed.image(value), null); } } } diff --git a/lib/src/widgets/toolbar/image_video_utils.dart b/lib/src/widgets/toolbar/image_video_utils.dart index bba8072b..a19cabe3 100644 --- a/lib/src/widgets/toolbar/image_video_utils.dart +++ b/lib/src/widgets/toolbar/image_video_utils.dart @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; -import '../../models/documents/nodes/embeddable.dart'; +import '../../models/documents/nodes/embed.dart'; import '../../translations/toolbar.i18n.dart'; import '../../utils/platform.dart'; import '../controller.dart'; @@ -75,7 +75,7 @@ class ImageVideoUtils { } if (imageUrl != null) { - controller.replaceText(index, length, Embeddable.image(imageUrl), null); + controller.replaceText(index, length, BlockEmbed.image(imageUrl), null); } } @@ -127,7 +127,7 @@ class ImageVideoUtils { } if (videoUrl != null) { - controller.replaceText(index, length, Embeddable.video(videoUrl), null); + controller.replaceText(index, length, BlockEmbed.video(videoUrl), null); } } diff --git a/lib/src/widgets/toolbar/video_button.dart b/lib/src/widgets/toolbar/video_button.dart index 947e2e90..a7220e80 100644 --- a/lib/src/widgets/toolbar/video_button.dart +++ b/lib/src/widgets/toolbar/video_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; -import '../../models/documents/nodes/embeddable.dart'; +import '../../models/documents/nodes/embed.dart'; import '../../models/themes/quill_dialog_theme.dart'; import '../../models/themes/quill_icon_theme.dart'; import '../controller.dart'; @@ -98,7 +98,7 @@ class VideoButton extends StatelessWidget { final index = controller.selection.baseOffset; final length = controller.selection.extentOffset - index; - controller.replaceText(index, length, Embeddable.video(value), null); + controller.replaceText(index, length, BlockEmbed.video(value), null); } } }