Skip to content

Commit

Permalink
perf: review tinymce code
Browse files Browse the repository at this point in the history
  • Loading branch information
anncwb committed Oct 22, 2020
1 parent 9c02d8e commit f75425d
Show file tree
Hide file tree
Showing 26 changed files with 349 additions and 534 deletions.
148 changes: 129 additions & 19 deletions src/components/Tinymce/src/Editor.vue
Original file line number Diff line number Diff line change
@@ -1,59 +1,169 @@
<template>
<div class="tinymce-container" :style="{ width: containerWidth }">
<tinymce-editor
:id="id"
:init="initOptions"
:modelValue="tinymceContent"
@update:modelValue="handleChange"
:tinymceScriptSrc="tinymceScriptSrc"
></tinymce-editor>
<textarea :id="tinymceId" visibility="hidden" ref="elRef"></textarea>
</div>
</template>

<script lang="ts">
import TinymceEditor from './lib'; // TinyMCE vue wrapper
import { defineComponent, computed } from 'vue';
import {
defineComponent,
computed,
onMounted,
nextTick,
ref,
unref,
watch,
onUnmounted,
onDeactivated,
} from 'vue';
import { basicProps } from './props';
import toolbar from './toolbar';
import plugins from './plugins';
import { getTinymce } from './getTinymce';
import { useScript } from '/@/hooks/web/useScript';
import { snowUuid } from '/@/utils/uuid';
import { bindHandlers } from './helper';
const CDN_URL = 'https://cdn.bootcdn.net/ajax/libs/tinymce/5.5.1';
const tinymceScriptSrc = `${CDN_URL}/tinymce.min.js`;
export default defineComponent({
name: 'Tinymce',
components: { TinymceEditor },
props: basicProps,
setup(props, { emit }) {
emits: ['change', 'update:modelValue'],
setup(props, { emit, attrs }) {
const editorRef = ref<any>(null);
const elRef = ref<Nullable<HTMLElement>>(null);
const tinymceId = computed(() => {
return snowUuid('tiny-vue');
});
const tinymceContent = computed(() => {
return props.value;
return props.modelValue;
});
function handleChange(value: string) {
emit('change', value);
}
const containerWidth = computed(() => {
const width = props.width;
// Test matches `100`, `'100'`
if (/^[\d]+(\.[\d]+)?$/.test(width.toString())) {
return `${width}px`;
}
return width;
});
const initOptions = computed(() => {
const { id, height, menubar } = props;
const { height, menubar } = props;
return {
selector: `#${id}`,
selector: `#${unref(tinymceId)}`,
height: height,
toolbar: toolbar,
theme: 'silver',
menubar: menubar,
plugins: plugins,
// 语言包
language_url: 'resource/tinymce/langs/zh_CN.js',
// 中文
language: 'zh_CN',
default_link_target: '_blank',
link_title: false,
advlist_bullet_styles: 'square',
advlist_number_styles: 'default',
object_resizing: false,
setup: (editor: any) => {
editorRef.value = editor;
editor.on('init', (e: Event) => initSetup(e));
},
};
});
return { containerWidth, initOptions, tinymceContent, handleChange, tinymceScriptSrc };
const { toPromise } = useScript({
src: tinymceScriptSrc,
});
watch(
() => attrs.disabled,
() => {
const editor = unref(editorRef);
if (!editor) return;
editor.setMode(attrs.disabled ? 'readonly' : 'design');
}
);
onMounted(() => {
nextTick(() => {
init();
});
});
onUnmounted(() => {
destory();
});
onDeactivated(() => {
destory();
});
function destory() {
if (getTinymce() !== null) {
getTinymce().remove(unref(editorRef));
}
}
function init() {
toPromise().then(() => {
initEditor();
});
}
function initEditor() {
getTinymce().init(unref(initOptions));
}
function initSetup(e: Event) {
const editor = unref(editorRef);
if (!editor) return;
const value = props.modelValue || '';
editor.setContent(value);
bindModelHandlers(editor);
bindHandlers(e, attrs, unref(editorRef));
}
function bindModelHandlers(editor: any) {
const modelEvents = attrs.modelEvents ? attrs.modelEvents : null;
const normalizedEvents = Array.isArray(modelEvents) ? modelEvents.join(' ') : modelEvents;
watch(
() => props.modelValue,
(val: string, prevVal: string) => {
if (
editor &&
typeof val === 'string' &&
val !== prevVal &&
val !== editor.getContent({ format: attrs.outputFormat })
) {
editor.setContent(val);
}
}
);
editor.on(normalizedEvents ? normalizedEvents : 'change keyup undo redo', () => {
emit('update:modelValue', editor.getContent({ format: attrs.outputFormat }));
});
}
function handleChange(value: string) {
emit('change', value);
}
return {
containerWidth,
initOptions,
tinymceContent,
handleChange,
tinymceScriptSrc,
elRef,
tinymceId,
};
},
});
</script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
const getGlobal = (): any => (typeof window !== 'undefined' ? window : global);

const getTinymce = () => {
export const getTinymce = () => {
const global = getGlobal();

return global && global.tinymce ? global.tinymce : null;
};

export { getTinymce };
81 changes: 81 additions & 0 deletions src/components/Tinymce/src/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
const validEvents = [
'onActivate',
'onAddUndo',
'onBeforeAddUndo',
'onBeforeExecCommand',
'onBeforeGetContent',
'onBeforeRenderUI',
'onBeforeSetContent',
'onBeforePaste',
'onBlur',
'onChange',
'onClearUndos',
'onClick',
'onContextMenu',
'onCopy',
'onCut',
'onDblclick',
'onDeactivate',
'onDirty',
'onDrag',
'onDragDrop',
'onDragEnd',
'onDragGesture',
'onDragOver',
'onDrop',
'onExecCommand',
'onFocus',
'onFocusIn',
'onFocusOut',
'onGetContent',
'onHide',
'onInit',
'onKeyDown',
'onKeyPress',
'onKeyUp',
'onLoadContent',
'onMouseDown',
'onMouseEnter',
'onMouseLeave',
'onMouseMove',
'onMouseOut',
'onMouseOver',
'onMouseUp',
'onNodeChange',
'onObjectResizeStart',
'onObjectResized',
'onObjectSelected',
'onPaste',
'onPostProcess',
'onPostRender',
'onPreProcess',
'onProgressState',
'onRedo',
'onRemove',
'onReset',
'onSaveContent',
'onSelectionChange',
'onSetAttrib',
'onSetContent',
'onShow',
'onSubmit',
'onUndo',
'onVisualAid',
];

const isValidKey = (key: string) => validEvents.indexOf(key) !== -1;

export const bindHandlers = (initEvent: Event, listeners: any, editor: any): void => {
Object.keys(listeners)
.filter(isValidKey)
.forEach((key: string) => {
const handler = listeners[key];
if (typeof handler === 'function') {
if (key === 'onInit') {
handler(initEvent, editor);
} else {
editor.on(key.substring(2), (e: any) => handler(e, editor));
}
}
});
};
72 changes: 0 additions & 72 deletions src/components/Tinymce/src/lib/ScriptLoader.ts

This file was deleted.

Loading

0 comments on commit f75425d

Please sign in to comment.