@windward/core 0.4.0 → 0.4.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/components/Content/Blocks/BlockQuote.vue +2 -2
- package/components/Content/Blocks/ClickableIcons.vue +1 -1
- package/components/Content/Blocks/Email.vue +10 -6
- package/components/Content/Blocks/Feedback.vue +12 -5
- package/components/Content/Blocks/OpenResponse.vue +7 -3
- package/components/Content/Blocks/OpenResponseCollate.vue +1 -1
- package/components/Content/Blocks/ScenarioChoice.vue +2 -2
- package/components/Content/Blocks/UserUpload/DisplayUserFilesTable.vue +2 -0
- package/components/Content/Blocks/UserUpload.vue +1 -0
- package/components/Content/Blocks/Video.vue +2 -2
- package/components/Navigation/Items/AskTheExpert.vue +1 -0
- package/components/Settings/AccordionSettings.vue +2 -0
- package/components/Settings/ClickableIconsSettings.vue +5 -1
- package/components/Settings/EmailSettings.vue +6 -1
- package/components/Settings/FeedbackSettings.vue +1 -0
- package/components/Settings/MathSettings.vue +1 -1
- package/components/Settings/ScenarioChoiceSettings.vue +1 -0
- package/components/Settings/TabSettings.vue +7 -1
- package/components/Settings/TextEditorSettings.vue +3 -2
- package/components/Settings/UserUploadSettings.vue +1 -1
- package/components/Settings/VideoSettings.vue +2 -0
- package/components/utils/FillInBlank/FillInBlankInput.vue +3 -0
- package/components/utils/MathExpressionEditor.vue +30 -9
- package/components/utils/MathLiveWrapper.vue +47 -25
- package/components/utils/TinyMCEWrapper.vue +102 -18
- package/components/utils/glossary/CourseGlossary.vue +2 -0
- package/config/tinymce.config.ts +17 -13
- package/helpers/MathHelper.ts +59 -0
- package/helpers/tinymce/WindwardPlugins.ts +335 -0
- package/i18n/en-US/components/utils/tiny_mce_wrapper.ts +1 -0
- package/i18n/es-ES/components/utils/tiny_mce_wrapper.ts +1 -0
- package/i18n/sv-SE/components/utils/tiny_mce_wrapper.ts +1 -0
- package/package.json +3 -2
- package/test/helpers/MathHelper.spec.js +14 -1
- package/tsconfig.json +4 -1
- package/helpers/tinymce/plugin.ts +0 -210
|
@@ -26,9 +26,27 @@
|
|
|
26
26
|
<v-btn-toggle dense multiple class="pt-1 d-flex justify-end">
|
|
27
27
|
<slot name="actions-prepend" :render="render"></slot>
|
|
28
28
|
<slot name="actions" :render="render">
|
|
29
|
+
<v-btn-toggle dense>
|
|
30
|
+
<v-btn v-if="render" color="primary" outlined @click="read">
|
|
31
|
+
<v-icon> mdi-play</v-icon>
|
|
32
|
+
</v-btn>
|
|
33
|
+
<v-btn
|
|
34
|
+
v-if="render"
|
|
35
|
+
color="primary"
|
|
36
|
+
outlined
|
|
37
|
+
@click="pause"
|
|
38
|
+
>
|
|
39
|
+
<v-icon> mdi-pause</v-icon>
|
|
40
|
+
</v-btn>
|
|
41
|
+
<v-btn v-if="render" color="primary" outlined @click="stop">
|
|
42
|
+
<v-icon> mdi-stop</v-icon>
|
|
43
|
+
</v-btn>
|
|
44
|
+
</v-btn-toggle>
|
|
45
|
+
|
|
29
46
|
<v-btn
|
|
30
47
|
v-if="render"
|
|
31
48
|
color="primary"
|
|
49
|
+
elevation="0"
|
|
32
50
|
outlined
|
|
33
51
|
@click="onClickOutside"
|
|
34
52
|
>{{
|
|
@@ -47,6 +65,7 @@
|
|
|
47
65
|
import _ from 'lodash'
|
|
48
66
|
import 'tinymce'
|
|
49
67
|
import Editor from '@tinymce/tinymce-vue'
|
|
68
|
+
import { getTinymce } from '@tinymce/tinymce-vue/lib/cjs/main/ts/TinyMCE'
|
|
50
69
|
|
|
51
70
|
/* Required TinyMCE components */
|
|
52
71
|
import 'tinymce/icons/default/icons.min.js'
|
|
@@ -96,11 +115,12 @@ import 'tinymce/skins/ui/oxide-dark/content.js'
|
|
|
96
115
|
import 'tinymce/skins/content/default/content.js'
|
|
97
116
|
import 'tinymce/skins/content/dark/content.js'
|
|
98
117
|
|
|
99
|
-
import { WindwardPlugins } from '../../helpers/tinymce/
|
|
118
|
+
import { WindwardPlugins } from '../../helpers/tinymce/WindwardPlugins'
|
|
100
119
|
import ContentCss from '!raw-loader!sass-loader!./assets/tinymce/content/global.scss'
|
|
101
120
|
import EditorCss from '!raw-loader!sass-loader!./assets/tinymce/ui/global.scss'
|
|
102
121
|
import Crypto from '~/helpers/Crypto'
|
|
103
122
|
import MathHelper from '../../helpers/MathHelper'
|
|
123
|
+
import { Synthesizer } from 'speechreader'
|
|
104
124
|
export default {
|
|
105
125
|
name: 'ContentEditorRichText',
|
|
106
126
|
components: {
|
|
@@ -108,7 +128,6 @@ export default {
|
|
|
108
128
|
},
|
|
109
129
|
props: {
|
|
110
130
|
value: { type: String, required: true, default: '' },
|
|
111
|
-
api_key: { type: String, required: true, default: '' },
|
|
112
131
|
height: { type: Number, required: false, default: null },
|
|
113
132
|
menubar: {
|
|
114
133
|
type: String,
|
|
@@ -119,7 +138,7 @@ export default {
|
|
|
119
138
|
type: String,
|
|
120
139
|
required: false,
|
|
121
140
|
default:
|
|
122
|
-
'undo redo |
|
|
141
|
+
'undo redo | styles | bold italic underline strikethrough removeformat | alignleft aligncenter alignright | table bullist numlist outdent indent | glossaryButton fibFormatButton mathButton ',
|
|
123
142
|
},
|
|
124
143
|
root_block: { type: String, required: false, default: 'div' },
|
|
125
144
|
label: { type: String, required: true, default: '' },
|
|
@@ -136,6 +155,8 @@ export default {
|
|
|
136
155
|
render: false,
|
|
137
156
|
text: '',
|
|
138
157
|
seed: Crypto.id(),
|
|
158
|
+
synthesizer: null,
|
|
159
|
+
paused: false,
|
|
139
160
|
}
|
|
140
161
|
},
|
|
141
162
|
watch: {
|
|
@@ -177,6 +198,7 @@ export default {
|
|
|
177
198
|
visual: false,
|
|
178
199
|
forced_root_block: this.root_block,
|
|
179
200
|
menubar: this.filteredMenubar,
|
|
201
|
+
toolbar_mode: 'sliding',
|
|
180
202
|
browser_spellcheck: true,
|
|
181
203
|
contextmenu: false,
|
|
182
204
|
statusbar: false,
|
|
@@ -187,8 +209,6 @@ export default {
|
|
|
187
209
|
body_class: this.isDarkTheme
|
|
188
210
|
? 'editor--theme-dark'
|
|
189
211
|
: 'editor--theme-light',
|
|
190
|
-
block_formats:
|
|
191
|
-
'Paragraph=p; Heading 3=h3; Heading 4=h4; Heading 5=h5; Heading 6=h6;',
|
|
192
212
|
menu: {
|
|
193
213
|
insert: {
|
|
194
214
|
title: 'Insert',
|
|
@@ -302,9 +322,11 @@ export default {
|
|
|
302
322
|
],
|
|
303
323
|
setup() {
|
|
304
324
|
// Here we can add plugin
|
|
305
|
-
|
|
325
|
+
getTinymce().PluginManager.add(
|
|
306
326
|
'WindwardToolKit',
|
|
307
|
-
|
|
327
|
+
(editor) => {
|
|
328
|
+
new WindwardPlugins(editor)
|
|
329
|
+
}
|
|
308
330
|
)
|
|
309
331
|
},
|
|
310
332
|
|
|
@@ -351,21 +373,59 @@ export default {
|
|
|
351
373
|
],
|
|
352
374
|
},
|
|
353
375
|
style_formats: [
|
|
354
|
-
{ title: 'Windward formats' },
|
|
355
376
|
{
|
|
356
|
-
title:
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
377
|
+
title: 'Headings',
|
|
378
|
+
items: [
|
|
379
|
+
{ title: 'Heading 2', format: 'h2' },
|
|
380
|
+
{ title: 'Heading 3', format: 'h3' },
|
|
381
|
+
{ title: 'Heading 4', format: 'h4' },
|
|
382
|
+
{ title: 'Heading 5', format: 'h5' },
|
|
383
|
+
{ title: 'Heading 6', format: 'h6' },
|
|
384
|
+
],
|
|
360
385
|
},
|
|
361
386
|
{
|
|
362
|
-
title:
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
387
|
+
title: 'Inline',
|
|
388
|
+
items: [
|
|
389
|
+
{ title: 'Bold', format: 'bold' },
|
|
390
|
+
{ title: 'Italic', format: 'italic' },
|
|
391
|
+
{ title: 'Underline', format: 'underline' },
|
|
392
|
+
{ title: 'Strikethrough', format: 'strikethrough' },
|
|
393
|
+
{ title: 'Superscript', format: 'superscript' },
|
|
394
|
+
{ title: 'Subscript', format: 'subscript' },
|
|
395
|
+
{ title: 'Code', format: 'code' },
|
|
396
|
+
],
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
title: 'Blocks',
|
|
400
|
+
items: [{ title: 'Paragraph', format: 'p' }],
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
title: 'Align',
|
|
404
|
+
items: [
|
|
405
|
+
{ title: 'Left', format: 'alignleft' },
|
|
406
|
+
{ title: 'Center', format: 'aligncenter' },
|
|
407
|
+
{ title: 'Right', format: 'alignright' },
|
|
408
|
+
{ title: 'Justify', format: 'alignjustify' },
|
|
409
|
+
],
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
title: 'Windward',
|
|
413
|
+
items: [
|
|
414
|
+
{
|
|
415
|
+
title: this.$t(
|
|
416
|
+
'windward.core.components.utils.tiny_mce_wrapper.term'
|
|
417
|
+
),
|
|
418
|
+
format: 'glossary',
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
title: this.$t(
|
|
422
|
+
'windward.core.components.utils.tiny_mce_wrapper.fill_blank'
|
|
423
|
+
),
|
|
424
|
+
format: 'fib',
|
|
425
|
+
},
|
|
426
|
+
],
|
|
366
427
|
},
|
|
367
428
|
],
|
|
368
|
-
style_formats_merge: true,
|
|
369
429
|
placeholder: this.label
|
|
370
430
|
? this.label
|
|
371
431
|
: this.$t(
|
|
@@ -390,7 +450,6 @@ export default {
|
|
|
390
450
|
importcss_append: true,
|
|
391
451
|
}
|
|
392
452
|
},
|
|
393
|
-
|
|
394
453
|
elementBody() {
|
|
395
454
|
const ele = document.querySelector('.tinymce-included-' + this.seed)
|
|
396
455
|
|
|
@@ -401,6 +460,31 @@ export default {
|
|
|
401
460
|
},
|
|
402
461
|
},
|
|
403
462
|
methods: {
|
|
463
|
+
read() {
|
|
464
|
+
if (this.paused) {
|
|
465
|
+
this.resume()
|
|
466
|
+
} else {
|
|
467
|
+
this.synthesizer = new Synthesizer(
|
|
468
|
+
MathHelper.convertMathContentToSpeakableText(this.text),
|
|
469
|
+
this.$i18n.locale
|
|
470
|
+
)
|
|
471
|
+
this.synthesizer.play()
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
pause() {
|
|
475
|
+
if (!this.paused) {
|
|
476
|
+
this.synthesizer.pause()
|
|
477
|
+
this.paused = true
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
resume() {
|
|
481
|
+
this.synthesizer.resume()
|
|
482
|
+
this.paused = false
|
|
483
|
+
},
|
|
484
|
+
stop() {
|
|
485
|
+
this.synthesizer.stop()
|
|
486
|
+
this.paused = false
|
|
487
|
+
},
|
|
404
488
|
onEditorFocus() {
|
|
405
489
|
if (!this.render) {
|
|
406
490
|
this.seed = Crypto.id()
|
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
<v-btn
|
|
102
102
|
color="error"
|
|
103
103
|
class="outlined"
|
|
104
|
+
elevation="0"
|
|
104
105
|
outlined
|
|
105
106
|
:disabled="
|
|
106
107
|
!$PermissionService.userHasAccessTo(
|
|
@@ -118,6 +119,7 @@
|
|
|
118
119
|
<v-btn
|
|
119
120
|
color="primary"
|
|
120
121
|
class="outlined"
|
|
122
|
+
elevation="0"
|
|
121
123
|
outlined
|
|
122
124
|
:disabled="
|
|
123
125
|
!$PermissionService.userHasAccessTo(
|
package/config/tinymce.config.ts
CHANGED
|
@@ -7,6 +7,7 @@ export default {
|
|
|
7
7
|
groups: [
|
|
8
8
|
{
|
|
9
9
|
name: 'windward.core.components.utils.math_expression_editor.basic',
|
|
10
|
+
type: 'basic',
|
|
10
11
|
buttons: [
|
|
11
12
|
{
|
|
12
13
|
cmd: false,
|
|
@@ -33,47 +34,46 @@ export default {
|
|
|
33
34
|
text: '\\%',
|
|
34
35
|
},
|
|
35
36
|
{
|
|
36
|
-
cmd:
|
|
37
|
+
cmd: false,
|
|
37
38
|
text: '\\pi',
|
|
38
|
-
latex: '\\pi',
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
|
-
cmd:
|
|
41
|
+
cmd: false,
|
|
42
42
|
text: 'x^2',
|
|
43
43
|
latex: '^2',
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
|
-
cmd:
|
|
47
|
-
text: '
|
|
46
|
+
cmd: false,
|
|
47
|
+
text: 'x^y',
|
|
48
48
|
latex: '^\\placeholder{}',
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
|
-
cmd:
|
|
52
|
-
text: '
|
|
51
|
+
cmd: false,
|
|
52
|
+
text: 'x_y',
|
|
53
53
|
latex: '_\\placeholder{}',
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
text: '\\sqrt{x}',
|
|
57
57
|
latex: '\\sqrt{\\placeholder{}}',
|
|
58
|
-
cmd:
|
|
58
|
+
cmd: false,
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
latex: '\\sqrt[\\placeholder{}]{\\placeholder{}}',
|
|
62
62
|
text: '\\sqrt[n]{x}',
|
|
63
|
-
cmd:
|
|
63
|
+
cmd: false,
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
|
-
cmd:
|
|
66
|
+
cmd: false,
|
|
67
67
|
text: '\\frac{x}{y}',
|
|
68
68
|
latex: '\\frac',
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
|
-
cmd:
|
|
71
|
+
cmd: false,
|
|
72
72
|
text: '\\left|x\\right|',
|
|
73
73
|
latex: '\\left|\\placeholder{}\\right|',
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
|
-
cmd:
|
|
76
|
+
cmd: false,
|
|
77
77
|
text: '\\left\\{x\\right\\}',
|
|
78
78
|
latex: '\\left\\{\\placeholder{}\\right\\}',
|
|
79
79
|
},
|
|
@@ -85,11 +85,11 @@ export default {
|
|
|
85
85
|
cmd: false,
|
|
86
86
|
text: '(x,y)',
|
|
87
87
|
},
|
|
88
|
-
|
|
89
88
|
],
|
|
90
89
|
},
|
|
91
90
|
{
|
|
92
91
|
name: 'windward.core.components.utils.math_expression_editor.operators',
|
|
92
|
+
type: 'operators',
|
|
93
93
|
buttons: [
|
|
94
94
|
{
|
|
95
95
|
cmd: false,
|
|
@@ -160,6 +160,7 @@ export default {
|
|
|
160
160
|
},
|
|
161
161
|
{
|
|
162
162
|
name: 'windward.core.components.utils.math_expression_editor.trigonometry',
|
|
163
|
+
type: 'trigonometry',
|
|
163
164
|
buttons: [
|
|
164
165
|
{
|
|
165
166
|
cmd: false,
|
|
@@ -201,6 +202,7 @@ export default {
|
|
|
201
202
|
},
|
|
202
203
|
{
|
|
203
204
|
name: 'windward.core.components.utils.math_expression_editor.greek',
|
|
205
|
+
type: 'greek',
|
|
204
206
|
buttons: [
|
|
205
207
|
{
|
|
206
208
|
cmd: false,
|
|
@@ -274,6 +276,7 @@ export default {
|
|
|
274
276
|
},
|
|
275
277
|
{
|
|
276
278
|
name: 'windward.core.components.utils.math_expression_editor.probability',
|
|
279
|
+
type: 'probability',
|
|
277
280
|
buttons: [
|
|
278
281
|
{
|
|
279
282
|
cmd: false,
|
|
@@ -300,6 +303,7 @@ export default {
|
|
|
300
303
|
},
|
|
301
304
|
{
|
|
302
305
|
name: 'windward.core.components.utils.math_expression_editor.eq_systems',
|
|
306
|
+
type: 'eq_systems',
|
|
303
307
|
buttons: [
|
|
304
308
|
{
|
|
305
309
|
cmd: false,
|
package/helpers/MathHelper.ts
CHANGED
|
@@ -163,6 +163,28 @@ export default class MathHelper {
|
|
|
163
163
|
return content
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Converts LaTeX content to speakable text.
|
|
168
|
+
*
|
|
169
|
+
* @param {string} content - The LaTeX content to be converted.
|
|
170
|
+
* @return {string}
|
|
171
|
+
*/
|
|
172
|
+
private static convertContentLatexToSpeakableText(content : string): string {
|
|
173
|
+
const regex = /\$\$.*?\$\$/g
|
|
174
|
+
|
|
175
|
+
const matches = content.match(regex)
|
|
176
|
+
if (matches) {
|
|
177
|
+
matches.forEach((match) => {
|
|
178
|
+
content = content.replace(
|
|
179
|
+
match,
|
|
180
|
+
mathLiveObject.convertLatexToSpeakableText(match)
|
|
181
|
+
)
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return content
|
|
186
|
+
}
|
|
187
|
+
|
|
166
188
|
/**
|
|
167
189
|
* convertContentSREnhancedLatexToHtml
|
|
168
190
|
* @param content
|
|
@@ -193,6 +215,29 @@ export default class MathHelper {
|
|
|
193
215
|
return content
|
|
194
216
|
}
|
|
195
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Converts enhanced LaTeX content to speakable text.
|
|
220
|
+
*
|
|
221
|
+
* @param {string} content - The enhanced LaTeX content to convert.
|
|
222
|
+
* @return {string}
|
|
223
|
+
*/
|
|
224
|
+
private static convertContentSREnhancedLatexToSpeakableText(content: string): string {
|
|
225
|
+
const regex = /\*\*.*?\*\*/g
|
|
226
|
+
|
|
227
|
+
const matches = content.match(regex)
|
|
228
|
+
if (matches) {
|
|
229
|
+
matches.forEach((match: any) => {
|
|
230
|
+
const mathObject = JSON.parse(match.replace(/\*\*/g, ''))
|
|
231
|
+
content = content.replace(
|
|
232
|
+
match,
|
|
233
|
+
mathObject.sr_text
|
|
234
|
+
)
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return content
|
|
239
|
+
}
|
|
240
|
+
|
|
196
241
|
/**
|
|
197
242
|
* convertMathContentToHtml
|
|
198
243
|
* @param content
|
|
@@ -208,6 +253,20 @@ export default class MathHelper {
|
|
|
208
253
|
).replace(/contenteditable="true"/g, '')
|
|
209
254
|
}
|
|
210
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Converts math content to speakable text.
|
|
258
|
+
*
|
|
259
|
+
* @param {string} content - The math content to be converted.
|
|
260
|
+
* @return {string} .
|
|
261
|
+
*/
|
|
262
|
+
public static convertMathContentToSpeakableText(content: string): string {
|
|
263
|
+
return MathHelper.convertContentSREnhancedLatexToSpeakableText(
|
|
264
|
+
MathHelper.convertContentLatexToSpeakableText(
|
|
265
|
+
MathHelper.convertContentMathMLtoLatex(content)
|
|
266
|
+
)
|
|
267
|
+
).replace(/contenteditable="true"/g, '')
|
|
268
|
+
}
|
|
269
|
+
|
|
211
270
|
/**
|
|
212
271
|
* convertMathMLToLatex
|
|
213
272
|
* @param content
|