@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
JavaScript
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