mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge pull request #628 from vincentdchan/feat/delta-to-json
feat: delta to json
This commit is contained in:
commit
ee5c9d410b
@ -4,18 +4,21 @@
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [],
|
||||
"attributes": {
|
||||
"subtype": "with-heading"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [],
|
||||
"attributes": {
|
||||
"tag": "*"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [],
|
||||
"attributes": {
|
||||
"text-type": "heading2",
|
||||
"check": true
|
||||
@ -23,6 +26,7 @@
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [],
|
||||
"attributes": {
|
||||
"text-type": "checkbox",
|
||||
"check": true
|
||||
@ -30,6 +34,7 @@
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [],
|
||||
"attributes": {
|
||||
"tag": "**"
|
||||
}
|
||||
|
@ -176,4 +176,11 @@ class TextNode extends Node {
|
||||
_delta = v;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Object> toJson() {
|
||||
final map = super.toJson();
|
||||
map['delta'] = _delta.toJson();
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ class StateTree {
|
||||
if (path.isEmpty) {
|
||||
return false;
|
||||
}
|
||||
var node = root.childAtPath(path);
|
||||
final node = root.childAtPath(path);
|
||||
if (node == null || node is! TextNode) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flowy_editor/document/attributes.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import './attributes.dart';
|
||||
@ -8,18 +9,14 @@ import './attributes.dart';
|
||||
// constant number: 2^53 - 1
|
||||
const int _maxInt = 9007199254740991;
|
||||
|
||||
class TextOperation {
|
||||
bool get isEmpty {
|
||||
return length == 0;
|
||||
}
|
||||
abstract class TextOperation {
|
||||
bool get isEmpty => length == 0;
|
||||
|
||||
int get length {
|
||||
return 0;
|
||||
}
|
||||
int get length;
|
||||
|
||||
Attributes? get attributes {
|
||||
return null;
|
||||
}
|
||||
Attributes? get attributes => null;
|
||||
|
||||
Map<String, dynamic> toJson();
|
||||
}
|
||||
|
||||
class TextInsert extends TextOperation {
|
||||
@ -54,6 +51,18 @@ class TextInsert extends TextOperation {
|
||||
return Object.hash(
|
||||
contentHash, attrs == null ? null : hashAttributes(attrs));
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
final result = <String, dynamic>{
|
||||
'insert': content,
|
||||
};
|
||||
final attrs = _attributes;
|
||||
if (attrs != null) {
|
||||
result['attributes'] = {...attrs};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class TextRetain extends TextOperation {
|
||||
@ -96,6 +105,18 @@ class TextRetain extends TextOperation {
|
||||
final attrs = _attributes;
|
||||
return Object.hash(_length, attrs == null ? null : hashAttributes(attrs));
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
final result = <String, dynamic>{
|
||||
'retain': _length,
|
||||
};
|
||||
final attrs = _attributes;
|
||||
if (attrs != null) {
|
||||
result['attributes'] = {...attrs};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class TextDelete extends TextOperation {
|
||||
@ -103,11 +124,6 @@ class TextDelete extends TextOperation {
|
||||
|
||||
TextDelete(int length) : _length = length;
|
||||
|
||||
@override
|
||||
bool get isEmpty {
|
||||
return length == 0;
|
||||
}
|
||||
|
||||
@override
|
||||
int get length {
|
||||
return _length;
|
||||
@ -129,6 +145,13 @@ class TextDelete extends TextOperation {
|
||||
int get hashCode {
|
||||
return _length.hashCode;
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'delete': _length,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class _OpIterator {
|
||||
@ -215,28 +238,17 @@ class _OpIterator {
|
||||
}
|
||||
}
|
||||
|
||||
Attributes? _attributesFromJSON(Map<String, dynamic>? json) {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
final result = <String, dynamic>{};
|
||||
|
||||
for (final entry in json.entries) {
|
||||
result[entry.key] = entry.value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TextOperation? _textOperationFromJson(Map<String, dynamic> json) {
|
||||
TextOperation? result;
|
||||
|
||||
if (json['insert'] is String) {
|
||||
result = TextInsert(json['insert'] as String,
|
||||
_attributesFromJSON(json['attributes'] as Map<String, dynamic>?));
|
||||
final attrs = json['attributes'] as Map<String, dynamic>?;
|
||||
result =
|
||||
TextInsert(json['insert'] as String, attrs == null ? null : {...attrs});
|
||||
} else if (json['retain'] is int) {
|
||||
result = TextRetain(json['retain'] as int,
|
||||
_attributesFromJSON(json['attributes'] as Map<String, Object>?));
|
||||
final attrs = json['attributes'] as Map<String, dynamic>?;
|
||||
result =
|
||||
TextRetain(json['retain'] as int, attrs == null ? null : {...attrs});
|
||||
} else if (json['delete'] is int) {
|
||||
result = TextDelete(json['delete'] as int);
|
||||
}
|
||||
@ -459,4 +471,8 @@ class Delta {
|
||||
});
|
||||
return inverted.chop();
|
||||
}
|
||||
|
||||
List<dynamic> toJson() {
|
||||
return operations.map((e) => e.toJson()).toList();
|
||||
}
|
||||
}
|
||||
|
@ -197,4 +197,37 @@ void main() {
|
||||
// expect(base.compose(delta).compose(inverted), base);
|
||||
// });
|
||||
});
|
||||
group('json', () {
|
||||
test('toJson()', () {
|
||||
final delta = Delta().retain(2).insert('A').delete(3);
|
||||
expect(delta.toJson(), [
|
||||
{'retain': 2},
|
||||
{'insert': 'A'},
|
||||
{'delete': 3}
|
||||
]);
|
||||
});
|
||||
test('attributes', () {
|
||||
final delta =
|
||||
Delta().retain(2, {'bold': true}).insert('A', {'italic': true});
|
||||
expect(delta.toJson(), [
|
||||
{
|
||||
'retain': 2,
|
||||
'attributes': {'bold': true},
|
||||
},
|
||||
{
|
||||
'insert': 'A',
|
||||
'attributes': {'italic': true},
|
||||
},
|
||||
]);
|
||||
});
|
||||
test('fromJson()', () {
|
||||
final delta = Delta.fromJson([
|
||||
{'retain': 2},
|
||||
{'insert': 'A'},
|
||||
{'delete': 3},
|
||||
]);
|
||||
final expected = Delta().retain(2).insert('A').delete(3);
|
||||
expect(delta, expected);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user