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.

185 lines (184 loc) 6.89 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const Quill = require("quill"); const image = require("../utils/image.cjs.js"); const scrollLock = require("../utils/scroll-lock.cjs.js"); const Delta = Quill.import("delta"); function resolveOptions(options) { return Object.assign({ // @ts-ignore Html2Canvas: window.Html2Canvas, useCORS: true, scale: 1, foreignObjectRendering: true, beforeCreateImage: void 0, beforeCreateCanvas: void 0 }, options); } function init() { const maskExits = document.querySelectorAll(".ql-screenshot-mask"); if (maskExits) { maskExits.forEach((item) => item && item.remove()); } const wrapper = document.createElement("div"); wrapper.classList.add("ql-screenshot-wrapper"); const mask = document.createElement("div"); mask.className = "ql-screenshot-mask"; const cutter = document.createElement("div"); cutter.className = "ql-screenshot-cutter"; const coordinate = document.createElement("p"); coordinate.className = "ql-screenshot-coordinate"; cutter.appendChild(coordinate); wrapper.appendChild(mask); wrapper.appendChild(cutter); document.body.appendChild(wrapper); return { wrapper, mask, cutter, coordinate }; } function findParentFixed(dom) { if (dom.tagName === "BODY") return false; if (["fixed", "sticky"].includes(dom.parentElement.style.position)) return true; return findParentFixed(dom.parentElement); } async function renderImage(Html2Canvas, html2canvasOptions, rect, options) { if (options && options.beforeCreateCanvas) { await options.beforeCreateCanvas(); } const canvas = await Html2Canvas(document.body, { ...html2canvasOptions, onclone: async (doc, el) => { const fixedDom = Array.from(doc.querySelectorAll('*[style*="position: fixed"]')); const stickyDom = Array.from(doc.querySelectorAll('*[style*="position: sticky"]')); const fixedDomList = /* @__PURE__ */ new Set([...fixedDom, ...stickyDom]); for (const dom of fixedDomList) { if (findParentFixed(dom)) continue; let x = 0; let y = 0; if (dom.style.top !== "auto") { y = window.scrollY; } if (dom.style.left !== "auto") { x = window.scrollX; } if (x !== 0 || y !== 0) { dom.style.transform = `translate(${x}px, ${y}px)`; } } const imgs = doc.querySelectorAll("img"); const promises = Array.from(imgs).map(async (img) => { img.src = await image.imgToBase64(img.src); }); await Promise.all(promises); html2canvasOptions.onclone && await html2canvasOptions.onclone(doc, el); } }); let cropCanvas = document.createElement("canvas"); cropCanvas.width = rect.width; cropCanvas.height = rect.height; const cropCanvasCtx = cropCanvas.getContext("2d"); cropCanvasCtx.drawImage( canvas, rect.x + window.scrollX, rect.y + window.scrollY, rect.width, rect.height, 0, 0, rect.width, rect.height ); if (options && options.beforeCreateImage) { cropCanvas = await options.beforeCreateImage(cropCanvas); } return typeof cropCanvas === "string" ? cropCanvas : cropCanvas.toDataURL(); } function Screenshot() { this.quill.options.screenshot = resolveOptions(this.quill.options.screenshot); const options = this.quill.options.screenshot; const { Html2Canvas, beforeCreateImage, beforeCreateCanvas, ...html2CanvasOptions } = options; if (!Html2Canvas) { throw new Error("ScreenShot module requires html2canvas. Please include the library on the page before FluentEditor."); } const range = this.quill.getSelection(); const { wrapper, mask, cutter, coordinate } = init(); const status = { leftClickLockFlag: false, start: void 0 }; const cleanLock = scrollLock.lockScroll(); const removeContextmenu = (event) => { event.preventDefault(); wrapper.remove(); cleanLock(); document.removeEventListener("contextmenu", removeContextmenu); }; const afterShotCtrl = async (event) => { document.removeEventListener("mousedown", toggleRect); const cutterRect = cutter.getBoundingClientRect(); const target = event.target; wrapper.remove(); cleanLock(); if (target && target.className === "ql-screenshot-confirm") { const image2 = await renderImage(Html2Canvas, html2CanvasOptions, cutterRect, { beforeCreateCanvas, beforeCreateImage }); const delta = new Delta().retain(range.index).delete(range.length).insert({ image: image2 }); this.quill.updateContents(delta, Quill.sources.USER); this.quill.setSelection(range.index + 1, Quill.sources.SILENT); } status.start = void 0; }; const drawRect = (event) => { const startX = status.start.x; const startY = status.start.y; const endX = event.clientX; const endY = event.clientY; const width = Math.abs(endX - startX); const height = Math.abs(endY - startY); const top = startY < endY ? startY : endY; const left = startX < endX ? startX : endX; const bottom = window.innerHeight - height - top; const right = window.innerWidth - width - left; const maskPath = ` linear-gradient(to top, #fff, #fff) top / 100% ${top}px, linear-gradient(to bottom, #fff, #fff) bottom /100% ${bottom}px, linear-gradient(to left, #fff, #fff) left / ${left}px 100%, linear-gradient(to right, #fff, #fff) right / ${right}px 100% `; Object.assign(cutter.style, { width: `${width}px`, height: `${height}px`, left: `${left}px`, top: `${top}px` }); Object.assign(mask.style, { "mask": maskPath, "-webkit-mask-repeat": "no-repeat" }); coordinate.textContent = `${width}, ${height}`; }; const toggleRect = (event) => { if (event.button === 2) { document.removeEventListener("mousemove", drawRect); document.removeEventListener("mousedown", toggleRect); document.addEventListener("contextmenu", removeContextmenu); return; } if (!status.leftClickLockFlag) { if (status.start) { document.removeEventListener("mousemove", drawRect); const doneBtn = document.createElement("div"); doneBtn.innerHTML = `<div class="ql-screenshot-confirm"></div><div class="ql-screenshot-cancel"></div>`; doneBtn.className = "ql-screenshot-done"; doneBtn.addEventListener("click", afterShotCtrl); coordinate.remove(); cutter.appendChild(doneBtn); status.leftClickLockFlag = true; } else { status.start = { x: event.clientX, y: event.clientY }; document.addEventListener("mousemove", drawRect); } } }; document.addEventListener("mousedown", toggleRect); } Screenshot.toolName = "screenshot"; exports.Screenshot = Screenshot; //# sourceMappingURL=screenshot.cjs.js.map