UNPKG

@opentiny/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.

141 lines (140 loc) 4.76 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import Quill from "quill"; import { merge } from "../../utils/merge.es.js"; import { CustomImage } from "./image.es.js"; import DefaultOptions from "./options.es.js"; import "./specs/index.es.js"; import { CustomImageSpec } from "./specs/custom-image-spec.es.js"; const dontMerge = (_destination, source) => source; class BlotFormatter { constructor(quill, options = {}) { __publicField(this, "options"); __publicField(this, "currentSpec"); __publicField(this, "specs"); __publicField(this, "overlay"); __publicField(this, "actions"); __publicField(this, "observer"); __publicField(this, "onClick", () => { this.hide(); }); this.quill = quill; this.options = merge({}, DefaultOptions, options, { arrayMerge: dontMerge }); if (options.allowInvalidUrl !== void 0) { this.options.allowInvalidUrl = options.allowInvalidUrl; } CustomImage.setOptions(this.options.allowInvalidUrl); 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": CustomImage, "modules/image-spec": 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 image = target.querySelector("img"); if (image) { this.repositionOverlay(); } } }); this.observer.observe(element, { attributes: true, attributeFilter: ["class"], attributeOldValue: true, subtree: 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.parentElement; 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: `${Math.min(specRect.width, parentRect.width)}px`, height: `${Math.min(specRect.height, parentRect.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); } }); } } export { BlotFormatter }; //# sourceMappingURL=blot-formatter.es.js.map