import 'dart:math' as math; import 'package:quill_delta/quill_delta.dart'; const Set WHITE_SPACE = { 0x9, 0xA, 0xB, 0xC, 0xD, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0xA0, 0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000 }; // Diff between two texts - old text and new text class Diff { // Start index in old text at which changes begin. final int start; /// The deleted text final String deleted; // The inserted text final String inserted; Diff(this.start, this.deleted, this.inserted); @override String toString() { return 'Diff[$start, "$deleted", "$inserted"]'; } } /* Get diff operation between old text and new text */ Diff getDiff(String oldText, String newText, int cursorPosition) { int end = oldText.length; int delta = newText.length - end; for (int limit = math.max(0, cursorPosition - delta); end > limit && oldText[end - 1] == newText[end + delta - 1]; end--) {} int start = 0; for (int startLimit = cursorPosition - math.max(0, delta); start < startLimit && oldText[start] == newText[start]; start++) {} String deleted = (start >= end) ? '' : oldText.substring(start, end); String inserted = newText.substring(start, end + delta); return Diff(start, deleted, inserted); } int getPositionDelta(Delta user, Delta actual) { DeltaIterator userItr = DeltaIterator(user); DeltaIterator actualItr = DeltaIterator(actual); int diff = 0; while (userItr.hasNext || actualItr.hasNext) { final length = math.min(userItr.peekLength(), actualItr.peekLength()); Operation userOperation = userItr.next(length); Operation actualOperation = actualItr.next(length); if (userOperation.length != actualOperation.length) { throw ('userOp ' + userOperation.length.toString() + ' does not match ' + ' actualOp ' + actualOperation.length.toString()); } if (userOperation.key == actualOperation.key) { continue; } else if (userOperation.isInsert && actualOperation.isRetain) { diff -= userOperation.length; } else if (userOperation.isDelete && actualOperation.isRetain) { diff += userOperation.length; } else if (userOperation.isRetain && actualOperation.isInsert) { String operationTxt = ''; if (actualOperation.data is String) { operationTxt = actualOperation.data as String; } if (operationTxt.startsWith('\n')) { continue; } diff += actualOperation.length; } } return diff; }