UNPKG

vue3-rich-editor

Version:
194 lines (193 loc) 6.18 kB
import { defineComponent as T, createElementBlock as S, openBlock as v, createElementVNode as o, createTextVNode as g, withModifiers as q, Fragment as F, renderList as I, toDisplayString as V } from "vue"; const W = { class: "rich-text-editor" }, _ = { class: "toolbar" }, $ = ["value"], H = ["innerHTML"], j = /* @__PURE__ */ T({ __name: "Vue3RichEditor", props: { value: {} }, emits: ["update-html"], setup(u, { emit: f }) { const m = f; let l = null; const p = [8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 72]; function x(t) { m("update-html", t.target.innerHTML); } function r() { const t = window.getSelection(); t && t.rangeCount > 0 && (l = t.getRangeAt(0)); } function i() { if (!l) return; const t = window.getSelection(); t && (t.removeAllRanges(), t.addRange(l)); } function b() { if (!l) return; const t = l.cloneContents(); if (!t || !t.firstChild) return; const e = document.createElement("span"); e.style.fontSize = "0", e.appendChild(t), l.deleteContents(), l.insertNode(e), l.selectNode(e); } function w(t) { const e = t.target; if (!e.value) return; const n = parseFloat(e.value); isNaN(n) || n <= 0 || k(n); } function k(t) { i(), b(), i(), document.queryCommandSupported("styleWithCSS") && document.execCommand("styleWithCSS", !1, "true"), document.execCommand("fontSize", !1, "7"); const e = document.querySelector(".editor"); e && (e.querySelectorAll('font[size="7"]').forEach((n) => { n.removeAttribute("size"), n.style.fontSize = t + "px"; }), e.querySelectorAll('span[style*="font-size"]').forEach((n) => { const s = n.style.fontSize.toLowerCase().trim(); (s.includes("large") || s.includes("small")) && (n.style.fontSize = t + "px"); })); } function h(t, e) { i(); const n = t.target; n.value && (document.queryCommandSupported("styleWithCSS") && document.execCommand("styleWithCSS", !1, "true"), e === "color" ? document.execCommand("foreColor", !1, n.value) : document.queryCommandSupported("hiliteColor") ? document.execCommand("hiliteColor", !1, n.value) : document.execCommand("backColor", !1, n.value)); } function M() { i(), document.execCommand("bold", !1); } function z() { i(), document.execCommand("italic", !1); } function E() { i(), document.execCommand("underline", !1); } function A() { i(), document.execCommand("strikeThrough", !1); } function C(t) { switch (i(), t) { case "left": document.execCommand("justifyLeft", !1); break; case "center": document.execCommand("justifyCenter", !1); break; case "right": document.execCommand("justifyRight", !1); break; } } const N = [ "color", "background-color", "font-size", "font-style", "font-weight", "text-decoration" ]; function R(t) { const e = t.querySelectorAll("*"); Array.from(e).forEach((n) => { const s = n, a = document.createElement("div"); for (N.forEach((c) => { const d = s.style[c]; d && (a.style.cssText += `${c}: ${d};`); }); s.firstChild; ) a.appendChild(s.firstChild); s.replaceWith(a); }); } function D(t) { t.preventDefault(); const e = t.clipboardData; if (!e) return; const n = e.getData("text/html") || e.getData("text/plain"), a = new DOMParser().parseFromString(n, "text/html"); R(a.body); const c = window.getSelection(); if (c && c.rangeCount > 0) { const d = c.getRangeAt(0); d.deleteContents(); const y = document.createDocumentFragment(); Array.from(a.body.childNodes).forEach((L) => y.appendChild(L)), d.insertNode(y); } } return (t, e) => (v(), S("div", W, [ o("div", _, [ o("label", null, [ e[5] || (e[5] = g(" 文字顏色: ")), o("input", { type: "color", onMousedown: r, onInput: e[0] || (e[0] = (n) => h(n, "color")) }, null, 32) ]), o("label", null, [ e[6] || (e[6] = g(" 背景顏色: ")), o("input", { type: "color", onMousedown: r, onInput: e[1] || (e[1] = (n) => h(n, "background-color")) }, null, 32) ]), o("label", null, [ e[7] || (e[7] = g(" 字體大小: ")), o("select", { onMousedown: q(r, ["stop"]), onChange: w }, [ (v(), S(F, null, I(p, (n) => o("option", { key: n, value: n }, V(n) + "px", 9, $)), 64)) ], 32) ]), o("button", { onMousedown: r, onClick: M }, "粗體", 32), o("button", { onMousedown: r, onClick: z }, "斜體", 32), o("button", { onMousedown: r, onClick: E }, "下劃線", 32), o("button", { onMousedown: r, onClick: A }, "刪除線", 32), o("button", { onMousedown: r, onClick: e[2] || (e[2] = (n) => C("left")) }, "靠左", 32), o("button", { onMousedown: r, onClick: e[3] || (e[3] = (n) => C("center")) }, "置中", 32), o("button", { onMousedown: r, onClick: e[4] || (e[4] = (n) => C("right")) }, "靠右", 32) ]), o("div", { class: "editor", contenteditable: "true", innerHTML: t.value, onInput: x, onPaste: D, style: { "min-height": "120px" } }, null, 40, H) ])); } }), B = (u, f) => { const m = u.__vccOpts || u; for (const [l, p] of f) m[l] = p; return m; }, P = /* @__PURE__ */ B(j, [["__scopeId", "data-v-b6f7478c"]]), U = { install(u) { u.component("Vue3RichEditor", P); } }; export { P as Vue3RichEditor, U as default };