From fc2e5d19b299b45dd1b9f0b5854947d31ffc6461 Mon Sep 17 00:00:00 2001
From: singerdmx <singerdmx@gmail.com>
Date: Mon, 21 Dec 2020 14:33:21 -0800
Subject: [PATCH] Fix equals method

---
 lib/models/documents/attribute.dart   | 20 ++++++++--------
 lib/models/documents/nodes/embed.dart | 33 ++++++++++++++++++++-------
 lib/models/documents/style.dart       |  8 +++++--
 3 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/lib/models/documents/attribute.dart b/lib/models/documents/attribute.dart
index 1ad8e737..b5c73eb2 100644
--- a/lib/models/documents/attribute.dart
+++ b/lib/models/documents/attribute.dart
@@ -1,3 +1,5 @@
+import 'package:quiver_hashcode/hashcode.dart';
+
 enum AttributeScope {
   INLINE, // refer to https://quilljs.com/docs/formats/#inline
   BLOCK, // refer to https://quilljs.com/docs/formats/#block
@@ -69,18 +71,18 @@ class Attribute<T> {
     return attribute;
   }
 
-
   @override
-  bool operator ==(Object other) =>
-      identical(this, other) ||
-      other is Attribute &&
-          runtimeType == other.runtimeType &&
-          key == other.key &&
-          scope == other.scope &&
-          value == other.value;
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    if (other is! Attribute<T>) return false;
+    Attribute<T> typedOther = other;
+    return key == typedOther.key &&
+        scope == typedOther.scope &&
+        value == typedOther.value;
+  }
 
   @override
-  int get hashCode => key.hashCode ^ scope.hashCode;
+  int get hashCode => hash3(key, scope, value);
 
   @override
   String toString() {
diff --git a/lib/models/documents/nodes/embed.dart b/lib/models/documents/nodes/embed.dart
index 9f0ed59d..5b8708ff 100644
--- a/lib/models/documents/nodes/embed.dart
+++ b/lib/models/documents/nodes/embed.dart
@@ -1,5 +1,8 @@
 import 'dart:collection';
 
+import 'package:collection/collection.dart';
+import 'package:quiver_hashcode/hashcode.dart';
+
 class Embeddable {
   static const TYPE_KEY = '_type';
   static const INLINE_KEY = '_inline';
@@ -36,16 +39,30 @@ class Embeddable {
   }
 
   @override
-  bool operator ==(Object other) =>
-      identical(this, other) ||
-      other is Embeddable &&
-          runtimeType == other.runtimeType &&
-          type == other.type &&
-          inline == other.inline &&
-          _data == other._data;
+  bool operator ==(dynamic other) {
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other is! Embeddable) {
+      return false;
+    }
+    final typedOther = other;
+    return typedOther.type == type &&
+        typedOther.inline == inline &&
+        DeepCollectionEquality().equals(typedOther._data, _data);
+  }
 
   @override
-  int get hashCode => type.hashCode ^ inline.hashCode ^ _data.hashCode;
+  int get hashCode {
+    if (_data.isEmpty) {
+      return hash2(type, inline);
+    }
+
+    final dataHash = hashObjects(
+      _data.entries.map((e) => hash2(e.key, e.value)),
+    );
+    return hash3(type, inline, dataHash);
+  }
 }
 
 class Span extends Embeddable {
diff --git a/lib/models/documents/style.dart b/lib/models/documents/style.dart
index 72161620..7d2262a8 100644
--- a/lib/models/documents/style.dart
+++ b/lib/models/documents/style.dart
@@ -84,8 +84,12 @@ class Style {
 
   @override
   bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other is! Style) return false;
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other is! Style) {
+      return false;
+    }
     Style typedOther = other;
     final eq = const MapEquality<String, Attribute>();
     return eq.equals(_attributes, typedOther._attributes);