add transform step during editor model update
parent
0e65f71a37
commit
f8f0e77bde
|
@ -19,6 +19,15 @@ import {diffAtCaret, diffDeletion} from "./diff";
|
||||||
import DocumentPosition from "./position";
|
import DocumentPosition from "./position";
|
||||||
import Range from "./range";
|
import Range from "./range";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback TransformCallback
|
||||||
|
* @param {DocumentPosition?} caretPosition the position where the caret should be position
|
||||||
|
* @param {string?} inputType the inputType of the DOM input event
|
||||||
|
* @param {object?} diff an object with `removed` and `added` strings
|
||||||
|
* @return {Number?} addedLen how many characters were added/removed (-) before the caret during the transformation step.
|
||||||
|
This is used to adjust the caret position.
|
||||||
|
*/
|
||||||
|
|
||||||
export default class EditorModel {
|
export default class EditorModel {
|
||||||
constructor(parts, partCreator, updateCallback = null) {
|
constructor(parts, partCreator, updateCallback = null) {
|
||||||
this._parts = parts;
|
this._parts = parts;
|
||||||
|
@ -26,7 +35,19 @@ export default class EditorModel {
|
||||||
this._activePartIdx = null;
|
this._activePartIdx = null;
|
||||||
this._autoComplete = null;
|
this._autoComplete = null;
|
||||||
this._autoCompletePartIdx = null;
|
this._autoCompletePartIdx = null;
|
||||||
|
this._transformCallback = null;
|
||||||
this.setUpdateCallback(updateCallback);
|
this.setUpdateCallback(updateCallback);
|
||||||
|
this._updateInProgress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set a callback for the transformation step.
|
||||||
|
* While processing an update, right before calling the update callback,
|
||||||
|
* a transform callback can be called, which serves to do modifications
|
||||||
|
* on the model that can span multiple parts. Also see `startRange()`.
|
||||||
|
* @param {TransformCallback} transformCallback
|
||||||
|
*/
|
||||||
|
setTransformCallback(transformCallback) {
|
||||||
|
this._transformCallback = transformCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
setUpdateCallback(updateCallback) {
|
setUpdateCallback(updateCallback) {
|
||||||
|
@ -133,6 +154,7 @@ export default class EditorModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
update(newValue, inputType, caret) {
|
update(newValue, inputType, caret) {
|
||||||
|
this._updateInProgress = true;
|
||||||
const diff = this._diff(newValue, inputType, caret);
|
const diff = this._diff(newValue, inputType, caret);
|
||||||
const position = this.positionForOffset(diff.at, caret.atNodeEnd);
|
const position = this.positionForOffset(diff.at, caret.atNodeEnd);
|
||||||
let removedOffsetDecrease = 0;
|
let removedOffsetDecrease = 0;
|
||||||
|
@ -147,11 +169,23 @@ export default class EditorModel {
|
||||||
}
|
}
|
||||||
this._mergeAdjacentParts();
|
this._mergeAdjacentParts();
|
||||||
const caretOffset = diff.at - removedOffsetDecrease + addedLen;
|
const caretOffset = diff.at - removedOffsetDecrease + addedLen;
|
||||||
const newPosition = this.positionForOffset(caretOffset, true);
|
let newPosition = this.positionForOffset(caretOffset, true);
|
||||||
this._setActivePart(newPosition, canOpenAutoComplete);
|
this._setActivePart(newPosition, canOpenAutoComplete);
|
||||||
|
if (this._transformCallback) {
|
||||||
|
const transformAddedLen = this._transform(newPosition, inputType, diff);
|
||||||
|
if (transformAddedLen !== 0) {
|
||||||
|
newPosition = this.positionForOffset(caretOffset + transformAddedLen, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._updateInProgress = false;
|
||||||
this._updateCallback(newPosition, inputType, diff);
|
this._updateCallback(newPosition, inputType, diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_transform(newPosition, inputType, diff) {
|
||||||
|
const result = this._transformCallback(newPosition, inputType, diff);
|
||||||
|
return Number.isFinite(result) ? result : 0;
|
||||||
|
}
|
||||||
|
|
||||||
_setActivePart(pos, canOpenAutoComplete) {
|
_setActivePart(pos, canOpenAutoComplete) {
|
||||||
const {index} = pos;
|
const {index} = pos;
|
||||||
const part = this._parts[index];
|
const part = this._parts[index];
|
||||||
|
@ -367,6 +401,8 @@ export default class EditorModel {
|
||||||
insertIdx += 1;
|
insertIdx += 1;
|
||||||
}
|
}
|
||||||
this._mergeAdjacentParts();
|
this._mergeAdjacentParts();
|
||||||
this._updateCallback();
|
if (!this._updateInProgress) {
|
||||||
|
this._updateCallback();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue