feat: rename delta and document (#153)
* chore: rename delta * fix: rename attributes to data * chore: rename document to page * fix: flutter analyze
This commit is contained in:
parent
6b5d48cfcb
commit
c573b9a80f
26 changed files with 243 additions and 247 deletions
|
|
@ -169,7 +169,7 @@ We'll use `network_image` in this case. And we add `network_image_src` to the `a
|
|||
```JSON
|
||||
{
|
||||
"type": "network_image",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"network_image_src": "https://docs.flutter.dev/assets/images/dash/dash-fainting.gif"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
{
|
||||
"document": {
|
||||
"type": "document",
|
||||
"type": "page",
|
||||
"children": [{
|
||||
"type": "heading",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"level": 2,
|
||||
"delta": [{
|
||||
"insert": "👋 "
|
||||
},
|
||||
{
|
||||
"insert": "Welcome to",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"bold": true
|
||||
}
|
||||
},
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
},
|
||||
{
|
||||
"insert": "AppFlowy Editor",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"href": "appflowy.io",
|
||||
"italic": true,
|
||||
"bold": true
|
||||
|
|
@ -30,13 +30,13 @@
|
|||
},
|
||||
{
|
||||
"type": "paragraph",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "paragraph",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": [{
|
||||
"insert": "AppFlowy Editor is a"
|
||||
},
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
},
|
||||
{
|
||||
"insert": "highly customizable",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"bold": true
|
||||
}
|
||||
},
|
||||
|
|
@ -54,7 +54,7 @@
|
|||
},
|
||||
{
|
||||
"insert": "rich-text editor",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"italic": true
|
||||
}
|
||||
},
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
},
|
||||
{
|
||||
"insert": "Flutter",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"underline": true
|
||||
}
|
||||
}
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
},
|
||||
{
|
||||
"type": "todo_list",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"checked": true,
|
||||
"delta": [{
|
||||
"insert": "Customizable"
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
},
|
||||
{
|
||||
"type": "todo_list",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"checked": true,
|
||||
"delta": [{
|
||||
"insert": "Test-covered"
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
},
|
||||
{
|
||||
"type": "todo_list",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"checked": false,
|
||||
"delta": [{
|
||||
"insert": "more to come!"
|
||||
|
|
@ -99,13 +99,13 @@
|
|||
},
|
||||
{
|
||||
"type": "paragraph",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "quote",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": [{
|
||||
"insert": "Here is an example you can give a try"
|
||||
}]
|
||||
|
|
@ -113,19 +113,19 @@
|
|||
},
|
||||
{
|
||||
"type": "paragraph",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "paragraph",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": [{
|
||||
"insert": "You can also use "
|
||||
},
|
||||
{
|
||||
"insert": "AppFlowy Editor",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"italic": true,
|
||||
"bold": true,
|
||||
"textColor": "0xffD70040",
|
||||
|
|
@ -140,13 +140,13 @@
|
|||
},
|
||||
{
|
||||
"type": "paragraph",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "bulleted_list",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": [{
|
||||
"insert": "Use / to insert blocks"
|
||||
}]
|
||||
|
|
@ -155,7 +155,7 @@
|
|||
},
|
||||
{
|
||||
"type": "bulleted_list",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": [{
|
||||
"insert": "Select text to trigger to the toolbar to format your notes."
|
||||
}]
|
||||
|
|
@ -164,13 +164,13 @@
|
|||
},
|
||||
{
|
||||
"type": "paragraph",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "paragraph",
|
||||
"attributes": {
|
||||
"data": {
|
||||
"delta": [{
|
||||
"insert": "If you have questions or feedback, please submit an issue on Github or join the community along with 1000+ builders!"
|
||||
}]
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@
|
|||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||
);
|
||||
name = "Thin Binary";
|
||||
outputPaths = (
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ export 'src/service/shortcut_event/shortcut_event.dart';
|
|||
export 'src/service/shortcut_event/shortcut_event_handler.dart';
|
||||
export 'src/render/rich_text/default_selectable.dart';
|
||||
export 'src/render/rich_text/flowy_rich_text.dart';
|
||||
export 'src/render/rich_text/flowy_rich_text_keys.dart';
|
||||
export 'src/render/selection_menu/selection_menu_widget.dart';
|
||||
export 'src/render/selection_menu/selection_menu_item_widget.dart';
|
||||
export 'src/l10n/l10n.dart';
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class Document {
|
|||
|
||||
factory Document.blank({bool withInitialText = false}) {
|
||||
final root = Node(
|
||||
type: 'document',
|
||||
type: 'page',
|
||||
children: withInitialText ? [paragraphNode()] : [],
|
||||
);
|
||||
return Document(
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import 'package:nanoid/nanoid.dart';
|
|||
///
|
||||
/// It contains three parts:
|
||||
/// - [type]: The type of the node to determine which block component to render it.
|
||||
/// - [attributes]: The attributes of the node to determine how to render it.
|
||||
/// - [data]: The data of the node to determine how to render it.
|
||||
/// - [children]: The children of the node.
|
||||
///
|
||||
///
|
||||
|
|
@ -41,7 +41,7 @@ final class Node extends ChangeNotifier with LinkedListEntry<Node> {
|
|||
factory Node.fromJson(Map<String, Object> json) {
|
||||
final node = Node(
|
||||
type: json['type'] as String,
|
||||
attributes: Attributes.from(json['attributes'] as Map? ?? {}),
|
||||
attributes: Attributes.from(json['data'] as Map? ?? {}),
|
||||
children: (json['children'] as List? ?? [])
|
||||
.map((e) => Map<String, Object>.from(e))
|
||||
.map((e) => Node.fromJson(e)),
|
||||
|
|
@ -195,7 +195,7 @@ final class Node extends ChangeNotifier with LinkedListEntry<Node> {
|
|||
.toList(growable: false);
|
||||
}
|
||||
if (attributes.isNotEmpty) {
|
||||
map['attributes'] = attributes;
|
||||
map['data'] = attributes;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// entry
|
||||
export 'entry/document_component.dart';
|
||||
export 'entry/page_block_component.dart';
|
||||
|
||||
// ime
|
||||
export 'service/ime/delta_input_service.dart';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class PageBlockKeys {
|
||||
const PageBlockKeys._();
|
||||
|
||||
static const String type = 'page';
|
||||
}
|
||||
|
||||
Node pageNode({
|
||||
required Iterable<Node> children,
|
||||
Attributes attributes = const {},
|
||||
}) {
|
||||
return Node(
|
||||
type: PageBlockKeys.type,
|
||||
children: children,
|
||||
attributes: attributes,
|
||||
);
|
||||
}
|
||||
|
||||
class PageBlockComponentBuilder extends BlockComponentBuilder {
|
||||
@override
|
||||
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
|
||||
return PageBlockComponent(
|
||||
key: blockComponentContext.node.key,
|
||||
node: blockComponentContext.node,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PageBlockComponent extends BlockComponentStatelessWidget {
|
||||
const PageBlockComponent({
|
||||
super.key,
|
||||
required super.node,
|
||||
super.showActions,
|
||||
super.actionBuilder,
|
||||
super.configuration = const BlockComponentConfiguration(),
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final editorState = Provider.of<EditorState>(context, listen: false);
|
||||
final children = editorState.renderer.buildList(context, node.children);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: children,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -49,13 +49,17 @@ void showColorMenu(
|
|||
}
|
||||
|
||||
void _formatHighlightColor(EditorState editorState, String color) {
|
||||
final selection = editorState.selection!;
|
||||
editorState.formatDelta(selection, {'highlightColor': color});
|
||||
editorState.formatDelta(
|
||||
editorState.selection,
|
||||
{FlowyRichTextKeys.highlightColor: color},
|
||||
);
|
||||
}
|
||||
|
||||
void _formatFontColor(EditorState editorState, String color) {
|
||||
final selection = editorState.selection!;
|
||||
editorState.formatDelta(selection, {'textColor': color});
|
||||
editorState.formatDelta(
|
||||
editorState.selection,
|
||||
{FlowyRichTextKeys.textColor: color},
|
||||
);
|
||||
}
|
||||
|
||||
List<ColorOption> _generateTextColorOptions(EditorState editorState) {
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@ final highlightColorItem = ToolbarItem(
|
|||
final nodes = editorState.getNodesInSelection(selection);
|
||||
final isHighlight = nodes.allSatisfyInSelection(selection, (delta) {
|
||||
return delta.everyAttributes(
|
||||
(attributes) {
|
||||
highlightColorHex = attributes['highlightColor'];
|
||||
return (highlightColorHex != null);
|
||||
},
|
||||
(attributes) => attributes[FlowyRichTextKeys.highlightColor] != null,
|
||||
);
|
||||
});
|
||||
return IconItemWidget(
|
||||
|
|
|
|||
|
|
@ -10,10 +10,7 @@ final textColorItem = ToolbarItem(
|
|||
final nodes = editorState.getNodesInSelection(selection);
|
||||
final isHighlight = nodes.allSatisfyInSelection(selection, (delta) {
|
||||
return delta.everyAttributes(
|
||||
(attributes) {
|
||||
textColorHex = attributes['textColor'];
|
||||
return (textColorHex != null);
|
||||
},
|
||||
(attributes) => attributes[FlowyRichTextKeys.textColor] != null,
|
||||
);
|
||||
});
|
||||
return IconItemWidget(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension NodeAttributesExtensions on Attributes {
|
||||
String? get heading {
|
||||
|
|
@ -24,14 +23,6 @@ extension NodeAttributesExtensions on Attributes {
|
|||
return null;
|
||||
}
|
||||
|
||||
bool get code {
|
||||
if (containsKey(BuiltInAttributeKey.code) &&
|
||||
this[BuiltInAttributeKey.code] is bool) {
|
||||
return this[BuiltInAttributeKey.code];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get check {
|
||||
if (containsKey(BuiltInAttributeKey.checkbox) &&
|
||||
this[BuiltInAttributeKey.checkbox] is bool) {
|
||||
|
|
@ -40,51 +31,3 @@ extension NodeAttributesExtensions on Attributes {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extension DeltaAttributesExtensions on Attributes {
|
||||
bool get bold {
|
||||
return (containsKey(BuiltInAttributeKey.bold) &&
|
||||
this[BuiltInAttributeKey.bold] == true);
|
||||
}
|
||||
|
||||
bool get italic {
|
||||
return (containsKey(BuiltInAttributeKey.italic) &&
|
||||
this[BuiltInAttributeKey.italic] == true);
|
||||
}
|
||||
|
||||
bool get underline {
|
||||
return (containsKey(BuiltInAttributeKey.underline) &&
|
||||
this[BuiltInAttributeKey.underline] == true);
|
||||
}
|
||||
|
||||
bool get strikethrough {
|
||||
return (containsKey(BuiltInAttributeKey.strikethrough) &&
|
||||
this[BuiltInAttributeKey.strikethrough] == true);
|
||||
}
|
||||
|
||||
static const whiteInt = 0XFFFFFFFF;
|
||||
|
||||
Color? get color {
|
||||
final textColor = this[BuiltInAttributeKey.textColor] as String?;
|
||||
if (textColor != null) {
|
||||
return textColor.toColor();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Color? get backgroundColor {
|
||||
final highlightColor = this[BuiltInAttributeKey.highlightColor] as String?;
|
||||
if (highlightColor != null) {
|
||||
return highlightColor.toColor();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String? get href {
|
||||
if (containsKey(BuiltInAttributeKey.href) &&
|
||||
this[BuiltInAttributeKey.href] is String) {
|
||||
return this[BuiltInAttributeKey.href];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class HTMLToNodesConverter {
|
|||
final childNodes = _document.body?.nodes.toList() ?? <html.Node>[];
|
||||
return Document.fromJson({
|
||||
'document': {
|
||||
'type': 'document',
|
||||
'type': 'page',
|
||||
'children': _handleContainer(childNodes).map((e) => e.toJson()).toList()
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -78,19 +78,19 @@ class DocumentHTMLDecoder extends Converter<String, Document> {
|
|||
Attributes? attributes;
|
||||
switch (localName) {
|
||||
case HTMLTags.bold || HTMLTags.strong:
|
||||
attributes = {'bold': true};
|
||||
attributes = {FlowyRichTextKeys.bold: true};
|
||||
break;
|
||||
case HTMLTags.italic || HTMLTags.em:
|
||||
attributes = {'italic': true};
|
||||
attributes = {FlowyRichTextKeys.italic: true};
|
||||
break;
|
||||
case HTMLTags.underline:
|
||||
attributes = {'underline': true};
|
||||
attributes = {FlowyRichTextKeys.underline: true};
|
||||
break;
|
||||
case HTMLTags.del:
|
||||
attributes = {'strikethrough': true};
|
||||
attributes = {FlowyRichTextKeys.strikethrough: true};
|
||||
break;
|
||||
case HTMLTags.code:
|
||||
attributes = {'code': true};
|
||||
attributes = {FlowyRichTextKeys.code: true};
|
||||
case HTMLTags.span:
|
||||
attributes = _getDeltaAttributesFromHTMLAttributes(
|
||||
element.attributes,
|
||||
|
|
@ -100,7 +100,7 @@ class DocumentHTMLDecoder extends Converter<String, Document> {
|
|||
final href = element.attributes['href'];
|
||||
if (href != null) {
|
||||
attributes = {
|
||||
'href': href,
|
||||
FlowyRichTextKeys.href: href,
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
|
@ -180,11 +180,11 @@ class DocumentHTMLDecoder extends Converter<String, Document> {
|
|||
final fontWeight = css['font-weight'];
|
||||
if (fontWeight != null) {
|
||||
if (fontWeight == 'bold') {
|
||||
attributes['bold'] = true;
|
||||
attributes[FlowyRichTextKeys.bold] = true;
|
||||
} else {
|
||||
final weight = int.tryParse(fontWeight);
|
||||
if (weight != null && weight >= 500) {
|
||||
attributes['bold'] = true;
|
||||
attributes[FlowyRichTextKeys.bold] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -196,10 +196,10 @@ class DocumentHTMLDecoder extends Converter<String, Document> {
|
|||
for (final decoration in decorations) {
|
||||
switch (decoration) {
|
||||
case 'underline':
|
||||
attributes['underline'] = true;
|
||||
attributes[FlowyRichTextKeys.underline] = true;
|
||||
break;
|
||||
case 'line-through':
|
||||
attributes['strike'] = true;
|
||||
attributes[FlowyRichTextKeys.strikethrough] = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -212,14 +212,14 @@ class DocumentHTMLDecoder extends Converter<String, Document> {
|
|||
if (backgroundColor != null) {
|
||||
final highlightColor = backgroundColor.tryToColor()?.toHex();
|
||||
if (highlightColor != null) {
|
||||
attributes['highlightColor'] = highlightColor;
|
||||
attributes[FlowyRichTextKeys.highlightColor] = highlightColor;
|
||||
}
|
||||
}
|
||||
|
||||
// italic
|
||||
final fontStyle = css['font-style'];
|
||||
if (fontStyle == 'italic') {
|
||||
attributes['italic'] = true;
|
||||
attributes[FlowyRichTextKeys.italic] = true;
|
||||
}
|
||||
|
||||
return attributes.isEmpty ? null : attributes;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,23 @@
|
|||
import 'dart:async';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:appflowy_editor/src/core/document/attributes.dart';
|
||||
import 'package:appflowy_editor/src/core/document/node.dart';
|
||||
import 'package:appflowy_editor/src/core/document/text_delta.dart';
|
||||
import 'package:appflowy_editor/src/core/location/position.dart';
|
||||
import 'package:appflowy_editor/src/core/location/selection.dart';
|
||||
import 'package:appflowy_editor/src/editor/toolbar/toolbar.dart';
|
||||
import 'package:appflowy_editor/src/editor_state.dart';
|
||||
import 'package:appflowy_editor/src/extensions/url_launcher_extension.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/flowy_rich_text_keys.dart';
|
||||
import 'package:appflowy_editor/src/render/selection/selectable.dart';
|
||||
import 'package:appflowy_editor/src/extensions/text_style_extension.dart';
|
||||
import 'package:appflowy_editor/src/editor/util/color_util.dart';
|
||||
import 'package:appflowy_editor/src/core/document/path.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
|
||||
const _kRichTextDebugMode = false;
|
||||
|
||||
typedef FlowyTextSpanDecorator = TextSpan Function(TextSpan textSpan);
|
||||
|
|
@ -376,3 +387,35 @@ class _FlowyRichTextState extends State<FlowyRichText> with SelectableMixin {
|
|||
return textSelection;
|
||||
}
|
||||
}
|
||||
|
||||
extension FlowyRichTextAttributes on Attributes {
|
||||
bool get bold => this[FlowyRichTextKeys.bold] == true;
|
||||
|
||||
bool get italic => this[FlowyRichTextKeys.italic] == true;
|
||||
|
||||
bool get underline => this[FlowyRichTextKeys.underline] == true;
|
||||
|
||||
bool get code => this[FlowyRichTextKeys.code] == true;
|
||||
|
||||
bool get strikethrough {
|
||||
return (containsKey(FlowyRichTextKeys.strikethrough) &&
|
||||
this[FlowyRichTextKeys.strikethrough] == true);
|
||||
}
|
||||
|
||||
Color? get color {
|
||||
final textColor = this[FlowyRichTextKeys.textColor] as String?;
|
||||
return textColor?.toColor();
|
||||
}
|
||||
|
||||
Color? get backgroundColor {
|
||||
final highlightColor = this[FlowyRichTextKeys.highlightColor] as String?;
|
||||
return highlightColor?.toColor();
|
||||
}
|
||||
|
||||
String? get href {
|
||||
if (this[FlowyRichTextKeys.href] is String) {
|
||||
return this[FlowyRichTextKeys.href];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
lib/src/render/rich_text/flowy_rich_text_keys.dart
Normal file
10
lib/src/render/rich_text/flowy_rich_text_keys.dart
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
class FlowyRichTextKeys {
|
||||
static String bold = 'bold';
|
||||
static String italic = 'italic';
|
||||
static String underline = 'underline';
|
||||
static String strikethrough = 'strikethrough';
|
||||
static String textColor = 'font_color';
|
||||
static String highlightColor = 'bg_color';
|
||||
static String code = 'code';
|
||||
static String href = 'href';
|
||||
}
|
||||
|
|
@ -227,7 +227,7 @@ ShortcutEventHandler markdownLinkOrImageHandler = (editorState, event) {
|
|||
textNode.path,
|
||||
Node.fromJson({
|
||||
'type': 'image',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'image_src': imgUrl,
|
||||
'align': 'center',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,37 +3,37 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
|||
const standardBlockComponentConfiguration = BlockComponentConfiguration();
|
||||
|
||||
final Map<String, BlockComponentBuilder> standardBlockComponentBuilderMap = {
|
||||
'document': DocumentComponentBuilder(),
|
||||
'paragraph': TextBlockComponentBuilder(
|
||||
PageBlockKeys.type: PageBlockComponentBuilder(),
|
||||
ParagraphBlockKeys.type: TextBlockComponentBuilder(
|
||||
configuration: standardBlockComponentConfiguration,
|
||||
),
|
||||
'todo_list': TodoListBlockComponentBuilder(
|
||||
TodoListBlockKeys.type: TodoListBlockComponentBuilder(
|
||||
configuration: standardBlockComponentConfiguration.copyWith(
|
||||
placeholderText: (_) => 'To-do',
|
||||
),
|
||||
),
|
||||
'bulleted_list': BulletedListBlockComponentBuilder(
|
||||
BulletedListBlockKeys.type: BulletedListBlockComponentBuilder(
|
||||
configuration: standardBlockComponentConfiguration.copyWith(
|
||||
placeholderText: (_) => 'List',
|
||||
),
|
||||
),
|
||||
'numbered_list': NumberedListBlockComponentBuilder(
|
||||
NumberedListBlockKeys.type: NumberedListBlockComponentBuilder(
|
||||
configuration: standardBlockComponentConfiguration.copyWith(
|
||||
placeholderText: (_) => 'List',
|
||||
),
|
||||
),
|
||||
'quote': QuoteBlockComponentBuilder(
|
||||
QuoteBlockKeys.type: QuoteBlockComponentBuilder(
|
||||
configuration: standardBlockComponentConfiguration.copyWith(
|
||||
placeholderText: (_) => 'Quote',
|
||||
),
|
||||
),
|
||||
'heading': HeadingBlockComponentBuilder(
|
||||
HeadingBlockKeys.type: HeadingBlockComponentBuilder(
|
||||
configuration: standardBlockComponentConfiguration.copyWith(
|
||||
placeholderText: (node) =>
|
||||
'Heading ${node.attributes[HeadingBlockKeys.level]}',
|
||||
),
|
||||
),
|
||||
'image': ImageBlockComponentBuilder(),
|
||||
ImageBlockKeys.type: ImageBlockComponentBuilder(),
|
||||
};
|
||||
|
||||
final List<CharacterShortcutEvent> standardCharacterShortcutEvents = [
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void main() async {
|
|||
'children': [
|
||||
{'type': 'text'}
|
||||
],
|
||||
'attributes': {'a': 'a'}
|
||||
'data': {'a': 'a'}
|
||||
}
|
||||
};
|
||||
final document = Document.fromJson(json);
|
||||
|
|
@ -78,11 +78,11 @@ void main() async {
|
|||
true,
|
||||
Document.fromJson({
|
||||
'document': {
|
||||
'type': 'document',
|
||||
'type': 'page',
|
||||
'children': [
|
||||
{
|
||||
'type': 'paragraph',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'delta': [],
|
||||
}
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ void main() async {
|
|||
true,
|
||||
Document.fromJson({
|
||||
'document': {
|
||||
'type': 'document',
|
||||
'type': 'page',
|
||||
'children': [],
|
||||
}
|
||||
}).isEmpty,
|
||||
|
|
@ -105,11 +105,11 @@ void main() async {
|
|||
true,
|
||||
Document.fromJson({
|
||||
'document': {
|
||||
'type': 'document',
|
||||
'type': 'page',
|
||||
'children': [
|
||||
{
|
||||
'type': 'paragraph',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'delta': [
|
||||
{'insert': ''}
|
||||
],
|
||||
|
|
@ -124,11 +124,11 @@ void main() async {
|
|||
false,
|
||||
Document.fromJson({
|
||||
'document': {
|
||||
'type': 'document',
|
||||
'type': 'page',
|
||||
'children': [
|
||||
{
|
||||
'type': 'paragraph',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'delta': [
|
||||
{'insert': 'Welcome to AppFlowy!'}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ void main() async {
|
|||
);
|
||||
expect(node.toJson(), {
|
||||
'type': 'example',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'example': 'example',
|
||||
},
|
||||
});
|
||||
|
|
@ -30,13 +30,13 @@ void main() async {
|
|||
);
|
||||
expect(nodeWithChildren.toJson(), {
|
||||
'type': 'example',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'example': 'example',
|
||||
},
|
||||
'children': [
|
||||
{
|
||||
'type': 'example',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'example': 'example',
|
||||
},
|
||||
},
|
||||
|
|
@ -57,7 +57,7 @@ void main() async {
|
|||
);
|
||||
expect(textNode.toJson(), {
|
||||
'type': 'text',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'example': 'example',
|
||||
},
|
||||
'delta': [
|
||||
|
|
@ -78,7 +78,7 @@ void main() async {
|
|||
);
|
||||
expect(textNodeWithChildren.toJson(), {
|
||||
'type': 'text',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'example': 'example',
|
||||
},
|
||||
'delta': [
|
||||
|
|
@ -87,7 +87,7 @@ void main() async {
|
|||
'children': [
|
||||
{
|
||||
'type': 'text',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'example': 'example',
|
||||
},
|
||||
'delta': [
|
||||
|
|
@ -185,7 +185,7 @@ void main() async {
|
|||
'children': [
|
||||
{
|
||||
'type': 'example',
|
||||
'attributes': {
|
||||
'data': {
|
||||
'example': 'example',
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue