recomputeDiff() {
    if (this.proposed.text !== this.current.text) {
      const ctext = this.current.text;
      const ptext = this.proposed.text;
      let sharedPrefixLength = 0;
      let sharedSuffixLength = 0;
      let minTextLength = Math.min(ctext.length, ptext.length);
      let i;

      for (i = 0; i < minTextLength; i++) {
        if (ptext[i] === ctext[i]) {
          sharedPrefixLength = i + 1;
        } else {
          break;
        }
      }

      for (i = 0; i < minTextLength - sharedPrefixLength; i++) {
        if (ptext[ptext.length - 1 - i] === ctext[ctext.length - 1 - i]) {
          sharedSuffixLength = i + 1;
        } else {
          break;
        }
      }

      const inserted = {
        start: sharedPrefixLength,
        end: ptext.length - sharedSuffixLength
      };
      const deleted = {
        start: sharedPrefixLength,
        end: ctext.length - sharedSuffixLength
      };
      inserted.text = ptext.substring(inserted.start, inserted.end);
      deleted.text = ctext.substring(deleted.start, deleted.end);
      this.inserted = inserted;
      this.deleted = deleted;
    } else {
      this.inserted = {
        start: this.proposed.selectedRange.start,
        end: this.proposed.selectedRange.start + this.proposed.selectedRange.length,
        text: ''
      };
      this.deleted = {
        start: this.current.selectedRange.start,
        end: this.current.selectedRange.start + this.current.selectedRange.length,
        text: ''
      };
    }
  }
Updates {TextFieldStateChange} inserted and {TextFieldStateChange} deleted
based on proposed and current