code: function modify(modifier, source, index, shift) {
    if (
      !this.isEnabled() &&
      source === Emitter.sources.USER &&
      !this.allowReadOnlyEdits
    ) {
      return new Delta();
    }
    let range = index == null ? null : this.getSelection();
    const oldDelta = this.editor.delta;
    const change = modifier();
    if (range != null) {
      if (index === true) {
        index = range.index; // eslint-disable-line prefer-destructuring
      }
      if (shift == null) {
        range = shiftRange(range, change, source);
      } else if (shift !== 0) {
        range = shiftRange(range, index, shift, source);
      }
      this.setSelection(range, Emitter.sources.SILENT);
    }
    if (change.length() > 0) {
      const args = [Emitter.events.TEXT_CHANGE, change, oldDelta, source];
      this.emitter.emit(Emitter.events.EDITOR_CHANGE, ...args);
      if (source !== Emitter.sources.SILENT) {
        this.emitter.emit(...args);
      }
    }
    return change;
  }
docs: Handle selection preservation and TEXT_CHANGE emission common to modification APIs