-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathcommands.ts
123 lines (106 loc) · 3.41 KB
/
commands.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import type { Editor, Component } from 'grapesjs';
import { PluginOptions } from '.';
import { commandNameCustomCode, keyCustomCode } from './utils';
type ContentTypes = HTMLElement | string | undefined;
export default (editor: Editor, opts: PluginOptions = {}) => {
const { modalTitle, codeViewOptions, commandCustomCode } = opts;
const appendToContent = (target: HTMLElement, content?: ContentTypes) => {
if (content instanceof HTMLElement) {
target.appendChild(content);
} else if (content) {
target.insertAdjacentHTML('beforeend', content);
}
}
// Add the custom code command
editor.Commands.add(commandNameCustomCode, {
keyCustomCode,
target: null as null | Component,
codeViewer: null as any,
run(editor, s, opts = {}) {
const target = opts.target || editor.getSelected();
this.target = target;
if (target?.get('editable')) {
this.showCustomCode(target, opts);
}
},
stop(editor) {
editor.Modal.close();
},
/**
* Method which tells how to show the custom code
* @param {Component} target
*/
showCustomCode(target: Component, options: any) {
const title = options.title || modalTitle;
const code = target.get(keyCustomCode) || '';
const content = this.getContent();
editor.Modal
.open({ title, content })
.onceClose(() => editor.stopCommand(commandNameCustomCode))
this.getCodeViewer().setContent(code);
},
/**
* Custom pre-content. Can be a simple string or an HTMLElement
*/
getPreContent() {},
/**
* Custom post-content. Can be a simple string or an HTMLElement
*/
getPostContent() {},
/**
* Get all the content for the custom code
* @return {HTMLElement}
*/
getContent() {
const codeViewer = this.getCodeViewer();
const content = document.createElement('div');
const pfx = editor.getConfig('stylePrefix');
content.className = `${pfx}custom-code`;
appendToContent(content, this.getPreContent() as ContentTypes);
content.appendChild(codeViewer.getElement());
appendToContent(content, this.getPostContent() as ContentTypes);
appendToContent(content, this.getContentActions());
codeViewer.refresh();
setTimeout(()=> codeViewer.focus(), 0);
return content;
},
/**
* Get the actions content. Can be a simple string or an HTMLElement
* @return {HTMLElement|String}
*/
getContentActions() {
const btn = document.createElement('button');
btn.setAttribute('type', 'button');
const pfx = editor.getConfig('stylePrefix');
btn.innerHTML = opts.buttonLabel!;
btn.className = `${pfx}btn-prim ${pfx}btn-import__custom-code`;
btn.onclick = () => this.handleSave();
return btn;
},
/**
* Handle the main save task
*/
handleSave() {
const { target } = this;
const code = this.getCodeViewer().getContent();
target?.set(keyCustomCode, code);
editor.Modal.close();
},
/**
* Return the code viewer instance
* @return {CodeViewer}
*/
getCodeViewer() {
if (!this.codeViewer) {
this.codeViewer = editor.CodeManager.createViewer({
codeName: 'htmlmixed',
theme: 'hopscotch',
readOnly: 0,
...codeViewOptions,
});
}
return this.codeViewer;
},
...commandCustomCode,
});
};