Skip to content

Instantly share code, notes, and snippets.

@gvergnaud
Last active July 9, 2024 13:05
Show Gist options
  • Save gvergnaud/631cf38804c8b5980c23f80229e31e99 to your computer and use it in GitHub Desktop.
Save gvergnaud/631cf38804c8b5980c23f80229e31e99 to your computer and use it in GitHub Desktop.
import { EditorState, Step, Transaction } from 'prosemirror-model';
type TransactionCreator = (state: EditorState) => Transaction;
const rebaseSteps = (stepsToRebase: Step[], committedSteps: Step[]): Step[] => {
if (!committedSteps.length) {
return stepsToRebase;
}
const committedStepsMaps = committedSteps.map((s) => s.getMap());
const stepsToRebaseMaps = stepsToRebase.map((s) => s.getMap());
// each step must be mapped to the following sequence
// [...inverted previous steps, ...commited steps, ...reapplied previous steps]
const rebasedSteps = stepsToRebase
.map((step, index) => {
const previousSteps = new Mapping(
stepsToRebaseMaps.slice(0, index),
);
const stepMapping = new Mapping();
// Apply inverted steps
stepMapping.appendMappingInverted(previousSteps);
// Append commited mapping
stepMapping.appendMapping(new Mapping(committedStepsMaps));
// Re apply all previous steps
stepMapping.appendMapping(previousSteps);
// Rebase current step
return step.map(stepMapping);
})
.filter(filterNullish);
return committedSteps.concat(rebasedSteps);
};
const rebaseCompose =
(f: TransactionCreator, g: TransactionCreator | null): TransactionCreator =>
(state) => {
if (!g) {
return f(state);
}
const steps1 = f(state).steps;
const steps2 = g(state).steps;
const steps3 = rebaseSteps(steps1, steps2);
return steps3.reduce(
(transaction, step) => transaction.step(step),
state.tr,
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment