|
@@ -1,3 +1,5 @@
|
|
|
+import 'package:flutter/foundation.dart';
|
|
|
+
|
|
|
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/path.dart';
|
|
@@ -33,7 +35,9 @@ class InsertOperation extends Operation {
|
|
|
|
|
|
factory InsertOperation.fromJson(Map<String, dynamic> json) {
|
|
|
final path = json['path'] as Path;
|
|
|
- final nodes = (json['nodes'] as List).map((n) => Node.fromJson(n));
|
|
|
+ final nodes = (json['nodes'] as List)
|
|
|
+ .map((n) => Node.fromJson(n))
|
|
|
+ .toList(growable: false);
|
|
|
return InsertOperation(path, nodes);
|
|
|
}
|
|
|
|
|
@@ -47,7 +51,7 @@ class InsertOperation extends Operation {
|
|
|
return {
|
|
|
'op': 'insert',
|
|
|
'path': path,
|
|
|
- 'nodes': nodes.map((n) => n.toJson()),
|
|
|
+ 'nodes': nodes.map((n) => n.toJson()).toList(growable: false),
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -55,6 +59,18 @@ class InsertOperation extends Operation {
|
|
|
Operation copyWith({Path? path}) {
|
|
|
return InsertOperation(path ?? this.path, nodes);
|
|
|
}
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool operator ==(Object other) {
|
|
|
+ if (identical(this, other)) return true;
|
|
|
+
|
|
|
+ return other is InsertOperation &&
|
|
|
+ other.path.equals(path) &&
|
|
|
+ other.nodes.equals(nodes);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ int get hashCode => path.hashCode ^ Object.hashAll(nodes);
|
|
|
}
|
|
|
|
|
|
/// [DeleteOperation] represents a delete operation.
|
|
@@ -66,7 +82,9 @@ class DeleteOperation extends Operation {
|
|
|
|
|
|
factory DeleteOperation.fromJson(Map<String, dynamic> json) {
|
|
|
final path = json['path'] as Path;
|
|
|
- final nodes = (json['nodes'] as List).map((n) => Node.fromJson(n));
|
|
|
+ final nodes = (json['nodes'] as List)
|
|
|
+ .map((n) => Node.fromJson(n))
|
|
|
+ .toList(growable: false);
|
|
|
return DeleteOperation(path, nodes);
|
|
|
}
|
|
|
|
|
@@ -80,7 +98,7 @@ class DeleteOperation extends Operation {
|
|
|
return {
|
|
|
'op': 'delete',
|
|
|
'path': path,
|
|
|
- 'nodes': nodes.map((n) => n.toJson()),
|
|
|
+ 'nodes': nodes.map((n) => n.toJson()).toList(growable: false),
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -88,6 +106,18 @@ class DeleteOperation extends Operation {
|
|
|
Operation copyWith({Path? path}) {
|
|
|
return DeleteOperation(path ?? this.path, nodes);
|
|
|
}
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool operator ==(Object other) {
|
|
|
+ if (identical(this, other)) return true;
|
|
|
+
|
|
|
+ return other is DeleteOperation &&
|
|
|
+ other.path.equals(path) &&
|
|
|
+ other.nodes.equals(nodes);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ int get hashCode => path.hashCode ^ Object.hashAll(nodes);
|
|
|
}
|
|
|
|
|
|
/// [UpdateOperation] represents an attributes update operation.
|
|
@@ -137,6 +167,20 @@ class UpdateOperation extends Operation {
|
|
|
{...oldAttributes},
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool operator ==(Object other) {
|
|
|
+ if (identical(this, other)) return true;
|
|
|
+
|
|
|
+ return other is UpdateOperation &&
|
|
|
+ other.path.equals(path) &&
|
|
|
+ mapEquals(other.attributes, attributes) &&
|
|
|
+ mapEquals(other.oldAttributes, oldAttributes);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ int get hashCode =>
|
|
|
+ path.hashCode ^ attributes.hashCode ^ oldAttributes.hashCode;
|
|
|
}
|
|
|
|
|
|
/// [UpdateTextOperation] represents a text update operation.
|
|
@@ -150,7 +194,7 @@ class UpdateTextOperation extends Operation {
|
|
|
factory UpdateTextOperation.fromJson(Map<String, dynamic> json) {
|
|
|
final path = json['path'] as Path;
|
|
|
final delta = Delta.fromJson(json['delta']);
|
|
|
- final inverted = Delta.fromJson(json['invert']);
|
|
|
+ final inverted = Delta.fromJson(json['inverted']);
|
|
|
return UpdateTextOperation(path, delta, inverted);
|
|
|
}
|
|
|
|
|
@@ -174,6 +218,19 @@ class UpdateTextOperation extends Operation {
|
|
|
Operation copyWith({Path? path}) {
|
|
|
return UpdateTextOperation(path ?? this.path, delta, inverted);
|
|
|
}
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool operator ==(Object other) {
|
|
|
+ if (identical(this, other)) return true;
|
|
|
+
|
|
|
+ return other is UpdateTextOperation &&
|
|
|
+ other.path.equals(path) &&
|
|
|
+ other.delta == delta &&
|
|
|
+ other.inverted == inverted;
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ int get hashCode => delta.hashCode ^ inverted.hashCode;
|
|
|
}
|
|
|
|
|
|
// TODO(Lucas.Xu): refactor this part
|