@dile/editor 2.2.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/DileEditor.js +51 -4
- package/src/DileI18nMixin.js +7 -0
- package/src/defaultToolbarConfig.js +19 -0
- package/src/dile-editor-image-dialog.js +7 -4
- package/src/dile-editor-link-dialog.js +17 -5
- package/src/dile-editor-markdown.js +24 -7
- package/src/dile-editor-toolbar-item.js +3 -3
- package/src/dile-editor-toolbar.js +50 -28
- package/src/i18n/en.js +8 -0
- package/src/i18n/es.js +8 -0
- package/src/prosemirror/menu-items.js +17 -12
- package/src/prosemirror/menu-plugin.js +4 -1
- package/src/prosemirror/toolbar-item.js +1 -0
- package/src/translationService.js +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dile/editor",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "Webcomponent to create a user editor interface, configured on various ways",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"url": "https://github.com/Polydile/dile-components/issues"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@dile/icons": "^2.0
|
|
33
|
-
"@dile/ui": "^2.
|
|
32
|
+
"@dile/icons": "^2.1.0",
|
|
33
|
+
"@dile/ui": "^2.3.1",
|
|
34
34
|
"lit": "^2.7.0 || ^3.0.0",
|
|
35
35
|
"prosemirror-commands": "^1.5.0",
|
|
36
36
|
"prosemirror-example-setup": "^1.2.1",
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"prosemirror-state": "^1.4.2",
|
|
42
42
|
"prosemirror-view": "^1.30.1"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "80e68858b65ac111ffba6ed72eee05df0a0aeb94"
|
|
45
45
|
}
|
package/src/DileEditor.js
CHANGED
|
@@ -4,8 +4,10 @@ import './dile-editor-markdown.js';
|
|
|
4
4
|
import '@dile/ui/components/pages/pages.js';
|
|
5
5
|
import '@dile/ui/components/tabs/tabs.js';
|
|
6
6
|
import { messageStyles } from '@dile/ui/components/input/index.js';
|
|
7
|
+
import { defaultToolbarConfig } from './defaultToolbarConfig.js';
|
|
8
|
+
import { DileI18nMixin } from './DileI18nMixin.js';
|
|
7
9
|
|
|
8
|
-
export class DileEditor extends DileEmmitChange(LitElement) {
|
|
10
|
+
export class DileEditor extends DileI18nMixin(DileEmmitChange(LitElement)) {
|
|
9
11
|
static styles = [
|
|
10
12
|
messageStyles,
|
|
11
13
|
css`
|
|
@@ -107,6 +109,15 @@ export class DileEditor extends DileEmmitChange(LitElement) {
|
|
|
107
109
|
opacity: 0.5;
|
|
108
110
|
}
|
|
109
111
|
|
|
112
|
+
.ProseMirror img {
|
|
113
|
+
max-width: 100%;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.ProseMirror code {
|
|
117
|
+
background-color: #eee;
|
|
118
|
+
padding: 0.4rem;
|
|
119
|
+
}
|
|
120
|
+
|
|
110
121
|
dile-tabs {
|
|
111
122
|
margin-bottom: 0.3rem;
|
|
112
123
|
}
|
|
@@ -152,15 +163,29 @@ export class DileEditor extends DileEmmitChange(LitElement) {
|
|
|
152
163
|
|
|
153
164
|
/** Hide errors on input */
|
|
154
165
|
hideErrorOnInput: { type: Boolean },
|
|
166
|
+
|
|
167
|
+
/** Disable toolbar items, string with items separated by tubes like "italic|h4" */
|
|
168
|
+
disableToolbarItems: { type: String },
|
|
169
|
+
|
|
170
|
+
addicionalCommands: { type: Object },
|
|
171
|
+
|
|
172
|
+
/** Menu config */
|
|
173
|
+
_menuConfig: { type: Object },
|
|
174
|
+
|
|
175
|
+
/** Language config */
|
|
155
176
|
};
|
|
156
177
|
}
|
|
157
178
|
|
|
158
179
|
constructor() {
|
|
159
180
|
super();
|
|
181
|
+
this.initialized = false;
|
|
160
182
|
this.value = this.innerHTML;
|
|
161
183
|
this.label = '';
|
|
162
184
|
this.viewSelected = 'design';
|
|
163
185
|
this.message = '';
|
|
186
|
+
this.disableToolbarItems = '';
|
|
187
|
+
this._menuConfig = {...defaultToolbarConfig};
|
|
188
|
+
this.addicionalCommands = {}
|
|
164
189
|
}
|
|
165
190
|
|
|
166
191
|
updated(changedProperties) {
|
|
@@ -170,10 +195,20 @@ export class DileEditor extends DileEmmitChange(LitElement) {
|
|
|
170
195
|
}
|
|
171
196
|
|
|
172
197
|
firstUpdated() {
|
|
198
|
+
this.setupMenuConfig();
|
|
173
199
|
this.editor = this.shadowRoot.getElementById('editor');
|
|
174
200
|
this.textarea = this.shadowRoot.getElementById('eltextarea');
|
|
175
201
|
}
|
|
176
202
|
|
|
203
|
+
setupMenuConfig() {
|
|
204
|
+
const disabledItems = this.disableToolbarItems.split('|');
|
|
205
|
+
disabledItems.forEach(item => {
|
|
206
|
+
if (this._menuConfig.hasOwnProperty(item)) {
|
|
207
|
+
this._menuConfig[item] = false;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
177
212
|
render() {
|
|
178
213
|
return html`
|
|
179
214
|
<div class="column-reverse">
|
|
@@ -193,7 +228,7 @@ export class DileEditor extends DileEmmitChange(LitElement) {
|
|
|
193
228
|
attrForSelected="name"
|
|
194
229
|
@dile-selected-changed=${this.tabSelectedChange}
|
|
195
230
|
>
|
|
196
|
-
<dile-tab name="design"
|
|
231
|
+
<dile-tab name="design">${this.translations.design_view}</dile-tab>
|
|
197
232
|
<dile-tab name="markdown">Markdown</dile-tab>
|
|
198
233
|
</dile-tabs>
|
|
199
234
|
</nav>
|
|
@@ -209,6 +244,10 @@ export class DileEditor extends DileEmmitChange(LitElement) {
|
|
|
209
244
|
<dile-editor-markdown
|
|
210
245
|
id="editor"
|
|
211
246
|
@dile-editor-change=${this.updateValue}
|
|
247
|
+
._menuConfig=${this._menuConfig}
|
|
248
|
+
@dile-editor-markdown-initialized=${this.setInitialized}
|
|
249
|
+
.addicionalCommands=${this.addicionalCommands}
|
|
250
|
+
language="${this.language}"
|
|
212
251
|
></dile-editor-markdown>
|
|
213
252
|
</section>
|
|
214
253
|
</dile-pages>
|
|
@@ -231,8 +270,12 @@ export class DileEditor extends DileEmmitChange(LitElement) {
|
|
|
231
270
|
}
|
|
232
271
|
|
|
233
272
|
updateEditorContent(value) {
|
|
234
|
-
this.
|
|
235
|
-
|
|
273
|
+
if(this.initialized) {
|
|
274
|
+
this.editor.updateEditorContent(value);
|
|
275
|
+
this.textarea.value = value;
|
|
276
|
+
} else {
|
|
277
|
+
setTimeout(() => this.updateEditorContent(value), 100);
|
|
278
|
+
}
|
|
236
279
|
}
|
|
237
280
|
|
|
238
281
|
get isValueExternalyUpdated() {
|
|
@@ -257,4 +300,8 @@ export class DileEditor extends DileEmmitChange(LitElement) {
|
|
|
257
300
|
this.message = '';
|
|
258
301
|
}
|
|
259
302
|
}
|
|
303
|
+
|
|
304
|
+
setInitialized() {
|
|
305
|
+
this.initialized = true;
|
|
306
|
+
}
|
|
260
307
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DileI18nMixin as OriginalDileI18nMixin } from '@dile/ui/mixins/i18n/DileI18nMixin.js';
|
|
2
|
+
import { translationService } from './translationService';
|
|
3
|
+
|
|
4
|
+
export const DileI18nMixin = (superclass) =>
|
|
5
|
+
class extends OriginalDileI18nMixin(translationService)(superclass) {
|
|
6
|
+
|
|
7
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const defaultToolbarConfig = {
|
|
2
|
+
bold: true,
|
|
3
|
+
italic: true,
|
|
4
|
+
code_mark: true,
|
|
5
|
+
link: true,
|
|
6
|
+
removeLink: true,
|
|
7
|
+
image: true,
|
|
8
|
+
unordered_list: true,
|
|
9
|
+
ordered_list: true,
|
|
10
|
+
lift: true,
|
|
11
|
+
paragraph: true,
|
|
12
|
+
h1: true,
|
|
13
|
+
h2: true,
|
|
14
|
+
h3: true,
|
|
15
|
+
h4: true,
|
|
16
|
+
code: true,
|
|
17
|
+
undo: true,
|
|
18
|
+
redo: true
|
|
19
|
+
};
|
|
@@ -3,8 +3,9 @@ import { NodeSelection } from "prosemirror-state"
|
|
|
3
3
|
import { schema } from "prosemirror-markdown";
|
|
4
4
|
import '@dile/ui/components/menu-overlay/menu-overlay.js';
|
|
5
5
|
import '@dile/ui/components/button/button.js';
|
|
6
|
+
import { DileI18nMixin } from './DileI18nMixin.js';
|
|
6
7
|
|
|
7
|
-
export class DileEditorImageDialog extends LitElement {
|
|
8
|
+
export class DileEditorImageDialog extends DileI18nMixin(LitElement) {
|
|
8
9
|
static styles = [
|
|
9
10
|
css`
|
|
10
11
|
:host {
|
|
@@ -30,11 +31,11 @@ export class DileEditorImageDialog extends LitElement {
|
|
|
30
31
|
<div slot="content">
|
|
31
32
|
<section class="grid">
|
|
32
33
|
<div>URL:</div>
|
|
33
|
-
<div><input type="text" id="src"
|
|
34
|
+
<div><input type="text" id="src"></div>
|
|
34
35
|
<div>Alt:</div>
|
|
35
|
-
<div><input type="text" id="alt"
|
|
36
|
+
<div><input type="text" id="alt"></div>
|
|
36
37
|
</section>
|
|
37
|
-
<dile-button @click=${this.accept}
|
|
38
|
+
<dile-button @click=${this.accept}>${this.translations.accept}</dile-button> <dile-button @click=${this.close}>${this.translations.cancel}</dile-button>
|
|
38
39
|
</div>
|
|
39
40
|
</dile-menu-overlay>
|
|
40
41
|
`;
|
|
@@ -69,6 +70,8 @@ export class DileEditorImageDialog extends LitElement {
|
|
|
69
70
|
alt: this.altInput.value,
|
|
70
71
|
}
|
|
71
72
|
}));
|
|
73
|
+
this.srcInput.value = '';
|
|
74
|
+
this.altInput.value = '';
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
customElements.define('dile-editor-image-dialog', DileEditorImageDialog);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { LitElement, html, css } from 'lit';
|
|
2
2
|
import '@dile/ui/components/menu-overlay/menu-overlay.js';
|
|
3
3
|
import '@dile/ui/components/button/button.js';
|
|
4
|
+
import { DileI18nMixin } from './DileI18nMixin.js';
|
|
4
5
|
|
|
5
|
-
export class DileEditorLinkDialog extends LitElement {
|
|
6
|
+
export class DileEditorLinkDialog extends DileI18nMixin(LitElement) {
|
|
6
7
|
static styles = [
|
|
7
8
|
css`
|
|
8
9
|
:host {
|
|
@@ -33,10 +34,10 @@ export class DileEditorLinkDialog extends LitElement {
|
|
|
33
34
|
<section class="grid">
|
|
34
35
|
<div>URL:</div>
|
|
35
36
|
<div><input type="text" id="url"></div>
|
|
36
|
-
<div
|
|
37
|
+
<div>${this.translations.title}:</div>
|
|
37
38
|
<div><input type="text" id="title"></div>
|
|
38
39
|
</section>
|
|
39
|
-
<dile-button @click=${this.accept}
|
|
40
|
+
<dile-button @click=${this.accept}>${this.translations.accept}</dile-button> <dile-button @click=${this.close}>${this.translations.cancel}</dile-button>
|
|
40
41
|
</div>
|
|
41
42
|
</dile-menu-overlay>
|
|
42
43
|
`;
|
|
@@ -45,6 +46,15 @@ export class DileEditorLinkDialog extends LitElement {
|
|
|
45
46
|
get menu() {
|
|
46
47
|
return this.shadowRoot.querySelector('dile-menu-overlay');
|
|
47
48
|
}
|
|
49
|
+
|
|
50
|
+
get urlInput() {
|
|
51
|
+
return this.shadowRoot.getElementById('url');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get titleInput() {
|
|
55
|
+
return this.shadowRoot.getElementById('title');
|
|
56
|
+
}
|
|
57
|
+
|
|
48
58
|
open() {
|
|
49
59
|
this.menu.open();
|
|
50
60
|
}
|
|
@@ -57,10 +67,12 @@ export class DileEditorLinkDialog extends LitElement {
|
|
|
57
67
|
bubbles: true,
|
|
58
68
|
composed: true,
|
|
59
69
|
detail: {
|
|
60
|
-
url: this.
|
|
61
|
-
title: this.
|
|
70
|
+
url: this.urlInput.value,
|
|
71
|
+
title: this.titleInput.value,
|
|
62
72
|
}
|
|
63
73
|
}));
|
|
74
|
+
this.urlInput.value = '';
|
|
75
|
+
this.titleInput.value = '';
|
|
64
76
|
}
|
|
65
77
|
}
|
|
66
78
|
customElements.define('dile-editor-link-dialog', DileEditorLinkDialog);
|
|
@@ -12,19 +12,37 @@ import { history } from "prosemirror-history";
|
|
|
12
12
|
import { buildKeymap } from "prosemirror-example-setup";
|
|
13
13
|
import './dile-editor-toolbar.js';
|
|
14
14
|
import { menuPlugin } from './prosemirror/menu-plugin.js';
|
|
15
|
+
import { DileI18nMixin } from './DileI18nMixin.js';
|
|
15
16
|
|
|
16
|
-
export class DileEditorMarkdown extends LitElement {
|
|
17
|
+
export class DileEditorMarkdown extends DileI18nMixin(LitElement) {
|
|
17
18
|
|
|
18
19
|
static styles = [
|
|
19
20
|
css`
|
|
21
|
+
* {
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
}
|
|
20
24
|
:host {
|
|
21
25
|
display: block;
|
|
22
26
|
}
|
|
23
27
|
`
|
|
24
28
|
];
|
|
25
29
|
|
|
30
|
+
static get properties() {
|
|
31
|
+
return {
|
|
32
|
+
_menuConfig: { type: Object },
|
|
33
|
+
addicionalCommands: { type: Object },
|
|
34
|
+
};
|
|
35
|
+
}
|
|
26
36
|
constructor() {
|
|
27
37
|
super();
|
|
38
|
+
this._menuConfig = {}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
createRenderRoot() {
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
firstUpdated() {
|
|
28
46
|
const editorElement = this;
|
|
29
47
|
const dispatchChange = this.dispatchChange.bind(this);
|
|
30
48
|
const state = this.createState('');
|
|
@@ -37,14 +55,13 @@ export class DileEditorMarkdown extends LitElement {
|
|
|
37
55
|
}
|
|
38
56
|
})
|
|
39
57
|
this.view = view;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
createRenderRoot() {
|
|
43
|
-
return this;
|
|
58
|
+
this.dispatchEvent(new CustomEvent('dile-editor-markdown-initialized'));
|
|
44
59
|
}
|
|
45
60
|
|
|
46
61
|
get editorMarkdown() {
|
|
47
|
-
|
|
62
|
+
if(this.view) {
|
|
63
|
+
return defaultMarkdownSerializer.serialize(this.view.state.doc);
|
|
64
|
+
}
|
|
48
65
|
}
|
|
49
66
|
|
|
50
67
|
createState(content) {
|
|
@@ -54,7 +71,7 @@ export class DileEditorMarkdown extends LitElement {
|
|
|
54
71
|
history(),
|
|
55
72
|
keymap(buildKeymap(schema)),
|
|
56
73
|
keymap(baseKeymap),
|
|
57
|
-
menuPlugin(),
|
|
74
|
+
menuPlugin(this._menuConfig, this.addicionalCommands, this.language),
|
|
58
75
|
]
|
|
59
76
|
})
|
|
60
77
|
}
|
|
@@ -2,8 +2,9 @@ import { LitElement, html, css } from 'lit';
|
|
|
2
2
|
import '@dile/ui/components/icon/icon.js';
|
|
3
3
|
import './dile-editor-link-dialog.js';
|
|
4
4
|
import './dile-editor-image-dialog.js';
|
|
5
|
+
import { DileI18nMixin } from './DileI18nMixin.js';
|
|
5
6
|
|
|
6
|
-
export class DileEditorToolbarItem extends LitElement {
|
|
7
|
+
export class DileEditorToolbarItem extends DileI18nMixin(LitElement) {
|
|
7
8
|
static styles = [
|
|
8
9
|
css`
|
|
9
10
|
:host {
|
|
@@ -37,8 +38,7 @@ export class DileEditorToolbarItem extends LitElement {
|
|
|
37
38
|
.icon=${this.item.icon}
|
|
38
39
|
@click=${this.doCommand}
|
|
39
40
|
></dile-icon>
|
|
40
|
-
|
|
41
|
-
<dile-editor-image-dialog id="imageDialog"></dile-editor-image-dialog>
|
|
41
|
+
${this.item.dialogTemplate ? this.item.dialogTemplate(this.language) : ''}
|
|
42
42
|
`;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -2,11 +2,12 @@ import { LitElement, html, css } from 'lit';
|
|
|
2
2
|
import { notesIcon } from '@dile/icons'
|
|
3
3
|
import './dile-editor-toolbar-item.js';
|
|
4
4
|
import '@dile/ui/components/select/select.js';
|
|
5
|
-
import {
|
|
5
|
+
import { getToolbarItems, getUndoItems, getBlockItems } from './prosemirror/menu-items.js';
|
|
6
6
|
import { linkCommand } from './prosemirror/markdown-commands.js';
|
|
7
7
|
import { schema } from "prosemirror-markdown";
|
|
8
|
+
import { DileI18nMixin } from './DileI18nMixin.js';
|
|
8
9
|
|
|
9
|
-
export class DileEditorToolbar extends LitElement {
|
|
10
|
+
export class DileEditorToolbar extends DileI18nMixin(LitElement) {
|
|
10
11
|
static styles = [
|
|
11
12
|
css`
|
|
12
13
|
:host {
|
|
@@ -25,6 +26,7 @@ export class DileEditorToolbar extends LitElement {
|
|
|
25
26
|
margin-bottom: 0;
|
|
26
27
|
--dile-input-border-width: 0;
|
|
27
28
|
--dile-input-padding: 3px;
|
|
29
|
+
--dile-input-background-color: var(--dile-editor-toolbar-block-background-color, #eee);
|
|
28
30
|
}
|
|
29
31
|
.marks, .blocks {
|
|
30
32
|
display: flex;
|
|
@@ -48,32 +50,41 @@ export class DileEditorToolbar extends LitElement {
|
|
|
48
50
|
toolbarItems: { type: Array },
|
|
49
51
|
blockItems: { type: Array },
|
|
50
52
|
undoItems: { type: Array },
|
|
53
|
+
menuConfig: { type: Object },
|
|
54
|
+
addicionalCommands: { type: Object },
|
|
51
55
|
};
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
constructor() {
|
|
55
59
|
super();
|
|
56
|
-
this.
|
|
57
|
-
|
|
58
|
-
this.undoItems = undoItems
|
|
59
|
-
|
|
60
|
-
this.blockItems = blockItems
|
|
60
|
+
this.addicionalCommands = {}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
get blockselect() {
|
|
64
|
+
return this.shadowRoot.getElementById('blockselect');
|
|
65
|
+
}
|
|
66
|
+
|
|
63
67
|
firstUpdated() {
|
|
64
|
-
|
|
65
|
-
this.
|
|
68
|
+
this.toolbarItems = getToolbarItems(this.menuConfig, this.addicionalCommands.toolbarItems || []);
|
|
69
|
+
this.undoItems = getUndoItems(this.menuConfig, this.addicionalCommands.undoItems || []);
|
|
70
|
+
this.blockItems = getBlockItems(this.menuConfig, this.addicionalCommands.blockItems || []);
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
render() {
|
|
69
74
|
return html`
|
|
70
|
-
${this.
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
${this.menuConfig
|
|
76
|
+
? html`
|
|
77
|
+
${this.showItems(this.toolbarItems, 'marks')}
|
|
78
|
+
${this.paragraphTypes}
|
|
79
|
+
${this.showItems(this.undoItems, 'blocks')}
|
|
80
|
+
`
|
|
81
|
+
: ''
|
|
82
|
+
}
|
|
73
83
|
`;
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
showItems(items, cssClass) {
|
|
87
|
+
if(!items) return '';
|
|
77
88
|
return html`
|
|
78
89
|
<div class="${cssClass}">
|
|
79
90
|
${items.map(item => html`
|
|
@@ -86,6 +97,7 @@ export class DileEditorToolbar extends LitElement {
|
|
|
86
97
|
@accept-link-dialog=${this.doLinkCommand}
|
|
87
98
|
@accept-image-dialog=${this.doImageCommand}
|
|
88
99
|
.editorView=${this.editorView}
|
|
100
|
+
language="${this.language}"
|
|
89
101
|
></dile-editor-toolbar-item>
|
|
90
102
|
`
|
|
91
103
|
: ''
|
|
@@ -97,21 +109,27 @@ export class DileEditorToolbar extends LitElement {
|
|
|
97
109
|
|
|
98
110
|
get paragraphTypes() {
|
|
99
111
|
return html`
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
${this.blockItems
|
|
113
|
+
? html `
|
|
114
|
+
<div class="blocks">
|
|
115
|
+
<dile-icon .icon=${notesIcon}></dile-icon>
|
|
116
|
+
<dile-select
|
|
117
|
+
id="blockselect"
|
|
118
|
+
name="blockselect"
|
|
119
|
+
@element-changed=${this.blockElementChanged}
|
|
120
|
+
quietOnStart
|
|
121
|
+
>
|
|
122
|
+
<select slot="select">
|
|
123
|
+
${this.blockItems.map(item => html`
|
|
124
|
+
<option value="${item.commandName}">${this.translations[item.commandName] || item.commandName}</option>
|
|
125
|
+
`)}
|
|
126
|
+
<option value="-"></option>
|
|
127
|
+
</select>
|
|
128
|
+
</dile-select>
|
|
129
|
+
</div>
|
|
130
|
+
`
|
|
131
|
+
: ''
|
|
132
|
+
}
|
|
115
133
|
`
|
|
116
134
|
}
|
|
117
135
|
|
|
@@ -140,7 +158,11 @@ export class DileEditorToolbar extends LitElement {
|
|
|
140
158
|
this.toolbarItems = this.computeActive(this.toolbarItems);
|
|
141
159
|
this.undoItems = this.computeActive(this.undoItems);
|
|
142
160
|
let currentBlock = this.blockItems.find(item => !item.command(this.editorView.state, null, this.editorView))
|
|
143
|
-
|
|
161
|
+
if(currentBlock) {
|
|
162
|
+
this.blockselect?.quietChange(currentBlock.commandName);
|
|
163
|
+
} else {
|
|
164
|
+
this.blockselect?.quietChange('-');
|
|
165
|
+
}
|
|
144
166
|
}
|
|
145
167
|
|
|
146
168
|
computeActive(items) {
|
package/src/i18n/en.js
ADDED
package/src/i18n/es.js
ADDED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
1
2
|
import { undo, redo } from "prosemirror-history";
|
|
2
3
|
import {
|
|
3
4
|
formatBoldIcon,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
} from './markdown-commands.js';
|
|
27
28
|
import { ToolbarItem, ToolbarLink, ToolbarRemoveLink, ToolbarImage } from "./toolbar-item.js";
|
|
28
29
|
|
|
29
|
-
export const
|
|
30
|
+
export const getToolbarItems = (config, additionalItems) => [
|
|
30
31
|
new ToolbarItem({
|
|
31
32
|
command: boldCommand,
|
|
32
33
|
commandName: 'bold',
|
|
@@ -46,6 +47,7 @@ export const toolbarItems = [
|
|
|
46
47
|
command: linkCommand,
|
|
47
48
|
commandName: 'link',
|
|
48
49
|
icon: insertLinkIcon,
|
|
50
|
+
dialogTemplate:(language) => html`<dile-editor-link-dialog language="${language}" id="linkDialog"></dile-editor-link-dialog> `,
|
|
49
51
|
}),
|
|
50
52
|
new ToolbarRemoveLink({
|
|
51
53
|
commandName: 'removeLink',
|
|
@@ -55,6 +57,7 @@ export const toolbarItems = [
|
|
|
55
57
|
command: linkCommand,
|
|
56
58
|
commandName: 'image',
|
|
57
59
|
icon: imageIcon,
|
|
60
|
+
dialogTemplate:(language) => html`<dile-editor-image-dialog language="${language}" id="imageDialog"></dile-editor-image-dialog> `,
|
|
58
61
|
}),
|
|
59
62
|
new ToolbarItem({
|
|
60
63
|
command: setUnorderedListCommand,
|
|
@@ -71,9 +74,10 @@ export const toolbarItems = [
|
|
|
71
74
|
commandName: 'lift',
|
|
72
75
|
icon: formatIndentDecreaseIcon,
|
|
73
76
|
}),
|
|
74
|
-
|
|
77
|
+
...additionalItems,
|
|
78
|
+
].filter(item => config[item.commandName] !== false);
|
|
75
79
|
|
|
76
|
-
export const
|
|
80
|
+
export const getUndoItems = (config, additionalItems) => [
|
|
77
81
|
new ToolbarItem({
|
|
78
82
|
command: undo,
|
|
79
83
|
commandName: 'undo',
|
|
@@ -83,14 +87,19 @@ export const undoItems = [
|
|
|
83
87
|
command: redo,
|
|
84
88
|
commandName: 'redo',
|
|
85
89
|
icon: redoIcon,
|
|
86
|
-
})
|
|
87
|
-
|
|
90
|
+
}),
|
|
91
|
+
...additionalItems,
|
|
92
|
+
].filter(item => config[item.commandName] !== false);
|
|
88
93
|
|
|
89
|
-
export const
|
|
94
|
+
export const getBlockItems = (config, additionalItems) => [
|
|
90
95
|
{
|
|
91
96
|
command: setParagraphCommand,
|
|
92
97
|
commandName: 'paragraph',
|
|
93
98
|
},
|
|
99
|
+
{
|
|
100
|
+
command: setCodeCommand,
|
|
101
|
+
commandName: 'code',
|
|
102
|
+
},
|
|
94
103
|
{
|
|
95
104
|
command: headingCommandCreator(1),
|
|
96
105
|
commandName: 'h1',
|
|
@@ -107,9 +116,5 @@ export const blockItems = [
|
|
|
107
116
|
command: headingCommandCreator(4),
|
|
108
117
|
commandName: 'h4',
|
|
109
118
|
},
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
commandName: 'code',
|
|
113
|
-
},
|
|
114
|
-
|
|
115
|
-
];
|
|
119
|
+
...additionalItems,
|
|
120
|
+
].filter(item => config[item.commandName] !== false);
|
|
@@ -2,12 +2,15 @@ import { Plugin } from "prosemirror-state";
|
|
|
2
2
|
|
|
3
3
|
const toolbarElement = 'dile-editor-toolbar';
|
|
4
4
|
|
|
5
|
-
export const menuPlugin = () => new Plugin({
|
|
5
|
+
export const menuPlugin = (menuConfig, addicionalCommands, language) => new Plugin({
|
|
6
6
|
view(editorView) {
|
|
7
7
|
let toolbar;
|
|
8
8
|
if (!editorView.dom.parentElement.querySelector(toolbarElement)) {
|
|
9
9
|
toolbar = document.createElement(toolbarElement);
|
|
10
|
+
toolbar.menuConfig = menuConfig;
|
|
10
11
|
toolbar.editorView = editorView;
|
|
12
|
+
toolbar.addicionalCommands = addicionalCommands;
|
|
13
|
+
toolbar.language = language;
|
|
11
14
|
editorView.dom.parentNode.insertBefore(toolbar, editorView.dom);
|
|
12
15
|
} else {
|
|
13
16
|
toolbar = editorView.dom.parentElement.querySelector(toolbarElement);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {TranslationService as OriginalTranslationService} from '@dile/ui/mixins/i18n/TranslationService.js';
|
|
2
|
+
|
|
3
|
+
class TranslationService extends OriginalTranslationService {
|
|
4
|
+
async importLanguage(language) {
|
|
5
|
+
const module = await import(`./i18n/${language}.js`);
|
|
6
|
+
return module;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async importFallback() {
|
|
10
|
+
const defaultModule = await import('./i18n/en.js');
|
|
11
|
+
return defaultModule;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const translationService = new TranslationService();
|