@stimulus-library/mixins
Version:
A library of useful controllers for Stimulus
68 lines (67 loc) • 2.94 kB
JavaScript
import { controllerMethod } from "@stimulus-library/utilities";
import { Controller } from "@hotwired/stimulus";
export class TrixComposableController extends Controller {
}
export function useTrixModifiers(controller) {
const controllerDisconnect = controller.disconnect.bind(controller);
let observing = false;
const observerCallback = (entries, observer) => {
entries.forEach(mutation => {
if (mutation.type === "childList" && Array.from(mutation.addedNodes).some((el) => el.tagName === "TRIX-TOOLBAR")) {
attemptSetup();
observer.disconnect();
}
});
};
const pasteHandler = (event) => controllerMethod(controller, "pasteEvent").call(controller, event);
const observer = new MutationObserver(observerCallback);
const attemptSetup = () => {
if (controller.element.tagName !== "TRIX-EDITOR") {
throw new Error("Expected controller to be mounted on an instance of <trix-editor>");
}
const editor = controller.element;
const editorParent = controller.element.parentElement;
if (editorParent == null) {
throw new Error("Could not traverse DOM tree from <trix-editor>");
}
editor.addEventListener("trix-paste", pasteHandler);
const toolbar = editorParent.querySelector("trix-toolbar");
if (!observing && !toolbar) {
observing = true;
observer.observe(editorParent, { childList: true });
return;
}
else if (!toolbar) {
throw new Error("Could not find an instance of <trix-toolbar> that is a sibling of this <trix-editor>");
}
else {
observer.disconnect();
}
controllerMethod(controller, "install").call(controller, { toolbar, editor });
};
const teardown = () => {
if (controller.element.tagName !== "TRIX-EDITOR") {
throw new Error("Expected controller to be mounted on an instance of <trix-editor>");
}
const editor = controller.element;
const editorParent = controller.element.parentElement;
if (editorParent == null) {
throw new Error("Could not traverse DOM tree from <trix-editor>");
}
editor.removeEventListener("trix-paste", pasteHandler);
const toolbar = editorParent.querySelector("trix-toolbar");
if (!toolbar) {
throw new Error("Could not find <trix-toolbar> that is a sibling of this <trix-editor> element");
}
controllerMethod(controller, "uninstall").call(controller, { toolbar, editor });
};
attemptSetup();
Object.assign(controller, {
disconnect() {
observer.disconnect();
teardown();
controllerMethod(controller, "uninstall").call({ toolbar, editor: controller.element });
controllerDisconnect();
},
});
}