UNPKG

faim

Version:

Element Plus & Element UI isomorphic UI component library, more than Element.

215 lines (213 loc) 8.04 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _lodashEs = require("lodash-es"); var _tinymce = _interopRequireDefault(require("tinymce/tinymce")); var _uuid = require("uuid"); var _vueDemi = require("vue-demi"); var _vueGlobalConfig = require("vue-global-config"); require("tinymce/models/dom"); require("tinymce/plugins/accordion"); require("tinymce/plugins/advlist"); require("tinymce/plugins/anchor"); require("tinymce/plugins/autolink"); require("tinymce/plugins/autosave"); require("tinymce/plugins/charmap"); require("tinymce/plugins/directionality"); require("tinymce/plugins/emoticons"); require("tinymce/plugins/emoticons/js/emojis.min"); require("tinymce/plugins/fullscreen"); require("tinymce/plugins/help"); require("tinymce/plugins/image"); require("tinymce/plugins/importcss"); require("tinymce/plugins/insertdatetime"); require("tinymce/plugins/link"); require("tinymce/plugins/lists"); require("tinymce/plugins/media"); require("tinymce/plugins/nonbreaking"); require("tinymce/plugins/pagebreak"); require("tinymce/plugins/preview"); require("tinymce/plugins/quickbars"); require("tinymce/plugins/save"); require("tinymce/plugins/searchreplace"); require("tinymce/plugins/table"); require("tinymce/plugins/visualblocks"); require("tinymce/plugins/visualchars"); require("tinymce/plugins/wordcount"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const model = { prop: _vueDemi.isVue3 ? "modelValue" : "value", event: _vueDemi.isVue3 ? "update:modelValue" : "input" }; const globalProps = {}; const globalAttrs = {}; const globalListeners = {}; const globalSlots = {}; module.exports = (0, _vueDemi.defineComponent)({ name: "FaRichText", install(app, options = {}) { const { props, attrs, listeners, slots } = (0, _vueGlobalConfig.resolveConfig)(options, { props: this.props, camelizePropNames: true }); Object.assign(globalProps, props); Object.assign(globalAttrs, attrs); Object.assign(globalListeners, listeners); Object.assign(globalSlots, slots); app.component(this.name, this); }, props: { [model.prop]: String, disabled: { type: Boolean, default: void 0 }, outputFormat: {} }, emits: [model.event, "init"], setup(props, { emit, expose, attrs }) { const id = (0, _vueDemi.ref)(`minimce-${(0, _uuid.v4)()}`); const preventSettingContent = (0, _vueDemi.ref)(false); const preventUpdatingModelValue = (0, _vueDemi.ref)(false); const Disabled = (0, _vueDemi.computed)(() => (0, _vueGlobalConfig.conclude)([props.disabled, globalProps.disabled], { type: Boolean })); const OutputFormat = (0, _vueDemi.computed)(() => (0, _vueGlobalConfig.conclude)([props.outputFormat, globalProps.outputFormat], { type: String })); const Options = (0, _vueDemi.computed)(() => (0, _vueGlobalConfig.conclude)([attrs, globalAttrs, { selector: `#${id.value}`, /** * 默认开启所有免费插件 * https://www.tiny.cloud/docs/tinymce/6/full-featured-open-source-demo/ */ plugins: "preview importcss searchreplace autolink autosave save directionality visualblocks visualchars fullscreen image link media table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help charmap quickbars emoticons accordion", menubar: "file edit view insert format tools table help", toolbar: "undo redo | accordion accordionremove | bold italic underline strikethrough | fontfamily fontsize blocks | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen preview save print | insertfile image media template link anchor codesample | ltr rtl", quickbars_selection_toolbar: "bold italic | quicklink h2 h3 blockquote quickimage quicktable", contextmenu: "link image table", branding: false, promotion: false, quickbars_insert_toolbar: false, // 默认屏蔽 iframe 原因: // - 允许用户引入未知的 iframe 存在执行未知脚本等安全隐患 // - 小程序侧不支持 iframe // - 小程序侧 web-view 中使用 iframe 需要配置业务域名 // - 给微信公众号 H5 侧带来授权问题 invalid_elements: "iframe,frame", // note that skin and content_css is disabled to avoid the normal // loading process and is instead loaded as a string via content_style skin: false, content_css: false, // skin: useDarkMode ? 'oxide-dark' : 'oxide', // content_css: useDarkMode ? 'dark' : 'default', autosave_ask_before_unload: false, // 改动后刷新,不再弹 alert autosave_interval: "30s", autosave_prefix: "{path}{query}-{id}-", autosave_restore_when_empty: false, autosave_retention: "2m", // importcss_append: true, // height: 500, relative_urls: false, convert_urls: false, image_advtab: true, image_caption: true, // 开启时,出现两个 bug:1. 部分菜单项失效;2. 拖拉拽调整视频大小会错位(该问题在 v6.0 仍在存在) media_live_embeds: false, toolbar_mode: "sliding", // toolbar_sticky: true, // toolbar_sticky_offset: isSmallScreen ? 102 : 108, // extended_valid_elements: 'img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name|referrerpolicy=no-referrer]', init_instance_callback: editor => { (0, _vueDemi.watch)(Disabled, n => { editor.mode.set(n ? "readonly" : "design"); }, { immediate: true }); const onContentChange = (0, _lodashEs.debounce)(() => { if (preventUpdatingModelValue.value) { preventUpdatingModelValue.value = false; return; } const newContent = editor.getContent({ format: OutputFormat.value }); if (newContent !== props[model.prop]) { preventSettingContent.value = true; emit(model.event, newContent); } }, 100); editor.on("Change input Redo Undo SetContent", onContentChange); (0, _vueDemi.watch)(() => props[model.prop], newModelValue => { if (preventSettingContent.value) { preventSettingContent.value = false; return; } preventUpdatingModelValue.value = true; editor.setContent(newModelValue || ""); }); setTimeout(() => { editor.setContent(props[model.prop] || ""); }); const wordcountButton = editor.getContainer().querySelector("button.tox-statusbar__wordcount"); wordcountButton?.click(); } }], { mergeFunction: (previousValue, currentValue) => (...args) => { previousValue(...args); currentValue(...args); }, type: Object })); (0, _vueDemi.onUnmounted)(() => { _tinymce.default.get(id.value)?.destroy(); }); (0, _vueDemi.onMounted)(() => { const el = document.querySelector(`#${id.value}`); const intersectionObserver = new IntersectionObserver(entries => { if (entries[0].isIntersecting) { intersectionObserver.unobserve(el); _tinymce.default.init(Options.value); } else {} }); if (el) { intersectionObserver.observe(el); } }); expose?.({ id }); return { id // loading, // height: (Options.value.height ?? '400') + 'px', }; }, render() { return _vueDemi.isVue3 ? (0, _vueDemi.h)("textarea", { id: this.id, class: "fa-rich-text" }) : (0, _vueDemi.h)("textarea", { attrs: { id: (0, _vueDemi.unref)(this.id), class: "fa-rich-text" }, on: { input: value => { this.$emit(model.event, value); } } }); } });