UNPKG

@cairn214/fluent-editor

Version:

A rich text editor based on Quill 2.0, which extends rich modules and formats on the basis of Quill. It's powerful and out-of-the-box.

136 lines (135 loc) 4.62 kB
"use strict"; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const lodashEs = require("lodash-es"); const Quill = require("quill"); const image = require("./image.cjs.js"); const Options = require("./Options.cjs.js"); const CustomImageSpec = require("./specs/CustomImageSpec.cjs.js"); const dontMerge = (_destination, source) => source; class BlotFormatter { constructor(quill, options = {}) { this.onClick = () => { this.hide(); }; this.hideImageOverlay = (event) => { var _a; const target = event.target; const isBlotFormatter = (_a = target == null ? void 0 : target.classList) == null ? void 0 : _a.contains("blot-formatter__overlay"); if (!isBlotFormatter) { this.hide(); } document.body.removeEventListener("click", this.hideImageOverlay); }; this.quill = quill; this.options = lodashEs.merge(Options.default, options, { arrayMerge: dontMerge }); this.currentSpec = null; this.actions = []; this.overlay = document.createElement("div"); this.overlay.classList.add(this.options.overlay.className); if (this.options.overlay.style) { Object.assign(this.overlay.style, this.options.overlay.style); } document.execCommand("enableObjectResizing", false, "false"); this.quill.root.addEventListener("click", this.onClick); this.specs = this.options.specs.map((SpecClass) => new SpecClass(this)); this.specs.forEach((spec) => spec.init()); } static register() { Quill.register("formats/image", image.default, true); Quill.register("formats/image-container", image.ImageContainerBlot, true); Quill.register("modules/image-spec", CustomImageSpec.CustomImageSpec, true); } show(spec) { this.currentSpec = spec; this.currentSpec.setSelection(); this.setUserSelect("none"); this.quill.root.parentNode.appendChild(this.overlay); this.repositionOverlay(); this.createActions(spec); const imageDom = spec.getTargetElement(); const win = window; const MutationObserver = win.MutationObserver || win.WebKitMutationObserver || win.MozMutationObserver; const element = imageDom.parentNode; this.observer = new MutationObserver((mutationList) => { for (const mutation of mutationList) { const target = mutation.target; const image2 = target.querySelector("img"); if (image2) { this.repositionOverlay(); } } }); this.observer.observe(element, { attributes: true, attributeFilter: ["class"], attributeOldValue: true, subtree: true }); document.body.addEventListener("click", this.hideImageOverlay, true); } hide() { if (!this.currentSpec) { return; } const imgDom = this.currentSpec.getTargetElement(); if (imgDom) { imgDom.classList.remove("current-select-img"); } this.currentSpec.onHide(); this.currentSpec = null; this.quill.root.parentNode.removeChild(this.overlay); this.overlay.style.setProperty("display", "none"); this.setUserSelect(""); this.destroyActions(); } update() { this.repositionOverlay(); this.actions.forEach((action) => action.onUpdate()); } createActions(spec) { this.actions = spec.getActions().map((ActionClass) => { const action = new ActionClass(this); action.onCreate(); return action; }); } destroyActions() { this.actions.forEach((action) => action.onDestroy()); this.actions = []; } repositionOverlay() { if (!this.currentSpec) { return; } const overlayTarget = this.currentSpec.getOverlayElement(); if (!overlayTarget) { return; } const parent = this.quill.root.parentNode; const specRect = overlayTarget.getBoundingClientRect(); const parentRect = parent.getBoundingClientRect(); Object.assign(this.overlay.style, { display: "block", left: `${specRect.left - parentRect.left - 1 + parent.scrollLeft}px`, top: `${specRect.top - parentRect.top + parent.scrollTop}px`, width: `${specRect.width}px`, height: `${specRect.height}px` }); } setUserSelect(value) { const props = [ "userSelect", "mozUserSelect", "webkitUserSelect", "msUserSelect" ]; props.forEach((prop) => { this.quill.root.style.setProperty(prop, value); if (document.documentElement) { document.documentElement.style.setProperty(prop, value); } }); } } exports.default = BlotFormatter; //# sourceMappingURL=BlotFormatter.cjs.js.map