style.dart 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import 'package:collection/collection.dart';
  2. import 'package:quiver/core.dart';
  3. import 'attribute.dart';
  4. class Style {
  5. Style() : _attributes = <String, Attribute>{};
  6. Style.attr(this._attributes);
  7. final Map<String, Attribute> _attributes;
  8. static Style fromJson(Map<String, dynamic>? attributes) {
  9. if (attributes == null) {
  10. return Style();
  11. }
  12. final result = attributes.map((key, value) {
  13. final attr = Attribute.fromKeyValue(key, value);
  14. return MapEntry<String, Attribute>(key, attr);
  15. });
  16. return Style.attr(result);
  17. }
  18. Map<String, dynamic>? toJson() => _attributes.isEmpty
  19. ? null
  20. : _attributes.map<String, dynamic>((_, attr) {
  21. return MapEntry<String, dynamic>(attr.key, attr.value);
  22. });
  23. // Properties
  24. Map<String, Attribute> get attributes => _attributes;
  25. Iterable<String> get keys => _attributes.keys;
  26. Iterable<Attribute> get values => _attributes.values;
  27. bool get isEmpty => _attributes.isEmpty;
  28. bool get isNotEmpty => _attributes.isNotEmpty;
  29. bool get isInline => isNotEmpty && values.every((ele) => ele.isInline);
  30. bool get isIgnored => isNotEmpty && values.every((ele) => ele.isIgnored);
  31. Attribute get single => values.single;
  32. bool containsKey(String key) => _attributes.containsKey(key);
  33. Attribute? getBlockExceptHeader() {
  34. for (final value in values) {
  35. if (value.isBlockExceptHeader) {
  36. return value;
  37. }
  38. }
  39. return null;
  40. }
  41. // Operators
  42. Style merge(Attribute attribute) {
  43. final merged = Map<String, Attribute>.from(_attributes);
  44. if (attribute.value == null) {
  45. merged.remove(attribute.key);
  46. } else {
  47. merged[attribute.key] = attribute;
  48. }
  49. return Style.attr(merged);
  50. }
  51. Style mergeAll(Style other) {
  52. var result = Style.attr(_attributes);
  53. other.values.forEach((attr) {
  54. result = result.merge(attr);
  55. });
  56. return result;
  57. }
  58. Style removeAll(Set<Attribute> attributes) {
  59. final merged = Map<String, Attribute>.from(_attributes);
  60. attributes.map((ele) => ele.key).forEach(merged.remove);
  61. return Style.attr(merged);
  62. }
  63. Style put(Attribute attribute) {
  64. final merged = Map<String, Attribute>.from(_attributes);
  65. merged[attribute.key] = attribute;
  66. return Style.attr(merged);
  67. }
  68. @override
  69. bool operator ==(Object other) {
  70. if (identical(this, other)) {
  71. return true;
  72. }
  73. if (other is! Style) {
  74. return false;
  75. }
  76. final typedOther = other;
  77. const eq = MapEquality<String, Attribute>();
  78. return eq.equals(_attributes, typedOther._attributes);
  79. }
  80. @override
  81. int get hashCode {
  82. final hashes =
  83. _attributes.entries.map((entry) => hash2(entry.key, entry.value));
  84. return hashObjects(hashes);
  85. }
  86. @override
  87. String toString() => "{${_attributes.values.join(', ')}}";
  88. }