I am writing a custom module for quilljs. It is a simple text macro replacement tool.
ie type ".hi", it will replace it with "hello".
Originally I was calling quill.setSelection(...) within the text-change event. It wasn't working Codepen Original. Eventually I found this in the docs
- Changes to text may cause changes to the selection (ex. typing advances the cursor), however during the text-change handler, the selection is not yet updated, and native browser behavior may place it in an inconsistent state. Use selection-change or editor-change for reliable selection updates." Quill setSelection API docs
So I reworked the code Codepen Revised. It works, but it sure is ugly and cursor updating after the text insertion looks weird. I cannot believe there isn't a better/idiomatic way to do this.
Quill.register("modules/quicktext", function (quill, options) {
let cache = "";
let finalcaret = null;
quill.on("editor-change", (eventName, ...args) => {
if (eventName === "text-change" && args[2] === "user") {
let [delta, oldDelta, source] = args;
console.log(source, delta);
let lastkey = delta.ops[delta.ops.length - 1]?.insert || "";
if (delta.ops[delta.ops.length - 1]?.delete) {
// handle delete key
cache = cache.slice(0, -1);
return;
}
if (lastkey && lastkey !== " ") {
cache += lastkey;
console.log("cache", cache, "lastkey", lastkey);
} else if (cache) {
// avoid initial call
console.log("cache", cache, "lastkey", lastkey);
reps.forEach((rep) => {
console.log("rep check", cache, rep[cache]);
if (rep[cache]) {
console.log("triggered");
let caret = quill.getSelection().index;
let start = caret - cache.length - 1;
quill.deleteText(start, cache.length, "api");
quill.insertText(start, rep[cache], "api");
//quill.update("api");
finalcaret = caret + rep[cache].length - cache.length;
console.log(
`caret at ${caret}, moving forward ${
rep[cache].length - cache.length
} spaces, to position ${
caret + rep[cache].length - cache.length
}.`
);
console.log("done trigger");
}
});
cache = "";
}
} else if (eventName === "selection-change") {
if (finalcaret) {
quill.setSelection(finalcaret);
finalcaret = "";
}
}
});
});
let reps = [
{ ".hi": "hello" },
{ ".bye": "goodbye" },
{ ".brb": "be right back" }
];
// We can now initialize Quill with something like this:
var quill = new Quill("#editor", {
modules: {
quicktext: {
reps: reps
}
}
});