Skip to content

Commit 562245e

Browse files
committed
progress
1 parent f384ddc commit 562245e

16 files changed

+270
-83
lines changed

dev/serve.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ app.use(VueEditr, {
1717
removeFormat: '<i class="mdi mdi-format-clear vue-wysiwyg-icon"></i>'
1818
},
1919
plainTextOnPaste: true,
20-
locale: 'ru',
20+
locale: 'de',
2121
});
2222

2323
app.mount('#app');

dev/serve.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ export default defineComponent({
1111
<div id="app">
1212
<div>
1313
<h4>First</h4>
14-
<vue-editr :customOptions="{addModules:['headings']}" />
14+
<vue-editr :customOptions="{addModules:['headings', 'orderedList', 'unorderedList']}" />
1515
</div>
1616
<div>
1717
<h4>Second</h4>
18-
<vue-editr />
18+
<vue-editr :customOptions="{plainTextOnPaste: false}" />
1919
</div>
2020
</div>
2121
</template>

src/VueEditr.vue

Lines changed: 29 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@ import {
77
onUnmounted,
88
inject,
99
} from 'vue';
10-
import {debounce} from 'ts-debounce';
10+
//import {debounce} from 'ts-debounce';
1111
import {EditrOptions, ModuleEvent} from '@/composables/interfaces';
12-
import useLoadModules from '@/composables/useLoadModules';
12+
import loadModules from '@/composables/useLoadModules';
1313
import {
1414
saveSelection,
1515
clearSelection,
1616
restoreSelection,
17-
} from '@/composables/selection';
17+
} from '@/composables/useSelection';
1818
19-
const defaultModules = ['bold', 'italic'];
19+
import onHandlers from '@/composables/useHandlers';
20+
21+
const defaultModules = ['bold', 'italic', 'underline', 'removeFormat'];
2022
2123
export default /*#__PURE__*/ defineComponent({
2224
name: 'VueEditr',
@@ -50,66 +52,24 @@ export default /*#__PURE__*/ defineComponent({
5052
defaultOptions = {...defaultOptions, ...$setupOptions};
5153
}
5254
const options: EditrOptions = props.customOptions
53-
? {...props.customOptions, ...defaultOptions}
55+
? {...defaultOptions, ...props.customOptions}
5456
: defaultOptions;
5557
56-
console.log('Custom Options', options);
57-
const editrModules = useLoadModules(
58+
const editrModules = loadModules(
5859
defaultModules,
5960
options?.hideModules,
6061
options?.addModules
6162
);
6263
63-
console.log('attributes', options);
64-
65-
/*const innerHTML = computed({
66-
get(): string {
67-
const elContent: HTMLElement = (content.value as unknown) as HTMLElement;
68-
return elContent.innerHTML;
69-
},
70-
set(html: string) {
71-
content.value = html;
72-
},
73-
});*/
74-
//const innerHTML = ((content.value as unknown) as HTMLElement).innerHTML;
64+
const {onPaste, onFocus, onInput, emitChange} = onHandlers(content, emit);
7565
76-
const emitChange = () => {
77-
emit('html', content.value?.innerHTML);
78-
emit('change', content.value?.innerHTML);
66+
const onDocumentClick = () => {
67+
closeAllMenus.value = !closeAllMenus.value;
7968
};
80-
const onContentBlur = () => {
69+
const onContentBlur = (): void => {
8170
range = saveSelection();
8271
emit('blur', content.value?.innerHTML);
8372
};
84-
const onPaste = (e: ClipboardEvent) => {
85-
e.preventDefault();
86-
const text = e.clipboardData?.getData('text/plain');
87-
document.execCommand('insertHTML', false, text);
88-
};
89-
const onFocus = () => {
90-
document.execCommand(
91-
'defaultParagraphSeparator',
92-
false,
93-
options.paragraphSeparator
94-
);
95-
};
96-
const onInput = debounce(emitChange, 300);
97-
const onDocumentClick = () => {
98-
closeAllMenus.value = !closeAllMenus.value;
99-
};
100-
101-
onMounted(() => {
102-
document.addEventListener('click', onDocumentClick);
103-
if (options.plainTextOnPaste) {
104-
content.value?.addEventListener('paste', onPaste);
105-
}
106-
});
107-
108-
onUnmounted(() => {
109-
if (options.plainTextOnPaste) {
110-
content.value?.removeEventListener('paste', onPaste);
111-
}
112-
});
11373
11474
const handle = (event: ModuleEvent) => {
11575
restoreSelection(range);
@@ -118,7 +78,7 @@ export default /*#__PURE__*/ defineComponent({
11878
emitChange();
11979
};
12080
121-
function moduleTitle(module: string): string {
81+
const moduleTitle = (module: string): string => {
12282
let title = '';
12383
if (options.localeStrings && options.localeStrings[module]) {
12484
title = options.localeStrings[module];
@@ -129,13 +89,25 @@ export default /*#__PURE__*/ defineComponent({
12989
);
13090
}
13191
return title;
132-
}
92+
};
93+
94+
onMounted(() => {
95+
document.addEventListener('click', onDocumentClick);
96+
if (options.plainTextOnPaste) {
97+
content.value?.addEventListener('paste', onPaste);
98+
}
99+
});
100+
101+
onUnmounted(() => {
102+
if (options.plainTextOnPaste) {
103+
content.value?.removeEventListener('paste', onPaste);
104+
}
105+
});
133106
134107
return {
135108
modules: computed(() => editrModules),
136109
content,
137110
onContentBlur,
138-
onPaste,
139111
onFocus,
140112
onInput,
141113
handle,
@@ -148,7 +120,7 @@ export default /*#__PURE__*/ defineComponent({
148120

149121
<template>
150122
<div class="editr">
151-
<menu class="editr--toolbar">
123+
<nav class="editr--toolbar">
152124
<keep-alive>
153125
<component
154126
v-for="(module, key) in modules"
@@ -159,7 +131,7 @@ export default /*#__PURE__*/ defineComponent({
159131
@handle="handle"
160132
></component>
161133
</keep-alive>
162-
</menu>
134+
</nav>
163135
<div
164136
ref="content"
165137
class="editr--body"

src/composables/interfaces.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,24 @@ export interface ModuleEvent {
3333
export interface ButtonProps {
3434
closeMenu: boolean;
3535
}
36+
37+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
38+
k: infer I
39+
) => void
40+
? I
41+
: never;
42+
43+
export type EmitFn<
44+
Options,
45+
Event extends keyof Options = keyof Options
46+
> = Options extends any[]
47+
? (event: Options[0], ...args: any[]) => void
48+
: Record<string, never> extends Options
49+
? (event: string, ...args: any[]) => void
50+
: UnionToIntersection<
51+
{
52+
[key in Event]: Options[key] extends (...args: infer Args) => any
53+
? (event: key, ...args: Args) => void
54+
: (event: key, ...args: any[]) => void;
55+
}[Event]
56+
>;

src/composables/useHandlers.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//import {saveSelection} from '@/composables/useSelection';
2+
import {debounce} from 'ts-debounce';
3+
import {Ref, EmitsOptions} from 'vue';
4+
import {EmitFn} from '@/composables/interfaces';
5+
6+
export default function onHandlers(
7+
content: Ref<HTMLElement | null>,
8+
emit: EmitFn<EmitsOptions>
9+
): Record<any, any> {
10+
const onFocus = (): void => {
11+
document.execCommand('defaultParagraphSeparator', false, 'div');
12+
};
13+
const onPaste = (e: ClipboardEvent): void => {
14+
e.preventDefault();
15+
const text = e.clipboardData?.getData('text/plain');
16+
document.execCommand('insertHTML', false, text);
17+
};
18+
const emitChange = (): void => {
19+
emit('html', content.value?.innerHTML);
20+
emit('change', content.value?.innerHTML);
21+
};
22+
23+
const onInput = debounce(emitChange, 300);
24+
25+
return {onPaste, onFocus, onInput, emitChange};
26+
}

src/composables/useLoadModules.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {ModuleObject} from './interfaces';
33
import {defineAsyncComponent} from 'vue';
44
//import mitt from 'mitt';
55

6-
export default function useLoadModules(
6+
export default function loadModules(
77
modules: Array<string>,
88
hideModules?: Array<string>,
99
addModules?: Array<string>
File renamed without changes.

src/modules/Bold.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script lang="ts">
22
import {defineComponent} from 'vue';
3-
import {ModuleEvent} from '../composables/interfaces';
3+
import {ModuleEvent} from '@/composables/interfaces';
44
55
export default /*#__PURE__*/ defineComponent({
66
name: 'ModuleBold',

src/modules/Headings.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts">
22
import {defineComponent} from 'vue';
3-
import {ModuleEvent} from '../composables/interfaces';
4-
import useButtonFunctions from '../composables/useButtonFunctions';
3+
import {ModuleEvent} from '@/composables/interfaces';
4+
import useButtonFunctions from '@/composables/useButtonFunctions';
55
66
export default /*#__PURE__*/ defineComponent({
77
name: 'ModuleHeadings',

src/modules/Italic.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script lang="ts">
22
import {defineComponent} from 'vue';
3-
import {ModuleEvent} from '../composables/interfaces';
3+
import {ModuleEvent} from '@/composables/interfaces';
44
55
export default /*#__PURE__*/ defineComponent({
66
name: 'ModuleBold',

0 commit comments

Comments
 (0)