import '../document/attribute.dart'; import '../document/document.dart'; import '../quill_delta.dart'; import 'insert.dart'; import 'delete.dart'; import 'format.dart'; enum RuleType { INSERT, DELETE, FORMAT, } abstract class Rule { const Rule(); RuleType get type; Delta? apply(Delta document, int index, {int? length, Object? data, Attribute? attribute}) { validateArgs(length, data, attribute); return applyRule( document, index, length: length, data: data, attribute: attribute, ); } Delta? applyRule(Delta document, int index, {int? length, Object? data, Attribute? attribute}); void validateArgs(int? length, Object? data, Attribute? attribute); } class Rules { Rules(this._rules); final List _rules; static final Rules _instance = Rules([ const FormatLinkAtCaretPositionRule(), const ResolveLineFormatRule(), const ResolveInlineFormatRule(), const InsertEmbedsRule(), const ForceNewlineForInsertsAroundEmbedRule(), const AutoExitBlockRule(), const PreserveBlockStyleOnInsertRule(), const PreserveLineStyleOnSplitRule(), const ResetLineFormatOnNewLineRule(), const AutoFormatLinksRule(), const PreserveInlineStylesRule(), const CatchAllInsertRule(), const EnsureEmbedLineRule(), const PreserveLineStyleOnMergeRule(), const CatchAllDeleteRule(), ]); static Rules getInstance() => _instance; Delta apply(RuleType ruleType, Document document, int index, {int? length, Object? data, Attribute? attribute}) { final delta = document.toDelta(); for (final rule in _rules) { if (rule.type != ruleType) { continue; } try { final result = rule.apply(delta, index, length: length, data: data, attribute: attribute); if (result != null) { return result..trim(); } } catch (e) { rethrow; } } throw 'Apply rules failed'; } }