@pie-element/select-text 11.0.1-next.0 → 11.0.2-esm.0

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.
@@ -0,0 +1,831 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import PropTypes from 'prop-types';
4
+ import TextField from '@material-ui/core/TextField';
5
+ import { withStyles } from '@material-ui/core/styles';
6
+ import cloneDeep from 'lodash/cloneDeep';
7
+ import debounce from 'lodash/debounce';
8
+ import { Tokenizer } from '@pie-lib/text-select';
9
+ import { layout, InputContainer, NumberTextField, FeedbackConfig, settings } from '@pie-lib/config-ui';
10
+ import Chip from '@material-ui/core/Chip';
11
+ import Info from '@material-ui/icons/Info';
12
+ import debug from 'debug';
13
+ import EditableHtml from '@pie-lib/editable-html';
14
+ import Tooltip from '@material-ui/core/Tooltip';
15
+ import { ModelUpdatedEvent, InsertImageEvent, DeleteImageEvent, InsertSoundEvent, DeleteSoundEvent } from '@pie-framework/pie-configure-events';
16
+
17
+ function _extends() {
18
+ _extends = Object.assign || function (target) {
19
+ for (var i = 1; i < arguments.length; i++) {
20
+ var source = arguments[i];
21
+
22
+ for (var key in source) {
23
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
24
+ target[key] = source[key];
25
+ }
26
+ }
27
+ }
28
+
29
+ return target;
30
+ };
31
+
32
+ return _extends.apply(this, arguments);
33
+ }
34
+
35
+ var createElementFromHTML = function createElementFromHTML() {
36
+ var htmlString = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
37
+ var div = document.createElement('div');
38
+ div.innerHTML = htmlString.trim();
39
+ return div;
40
+ };
41
+
42
+ var parseParagraph = function parseParagraph(paragraph, end) {
43
+ if (end) {
44
+ return paragraph.innerHTML;
45
+ }
46
+
47
+ return ''.concat(paragraph.innerHTML, '\n\n');
48
+ };
49
+
50
+ var parseParagraphs = function parseParagraphs(dom) {
51
+ var paragraphs = dom.querySelectorAll('div[separator=true]'); // separate variable for easily debugging, if needed
52
+
53
+ var str = '';
54
+ paragraphs.forEach(function (par, index) {
55
+ str += parseParagraph(par, index === paragraphs.length - 1);
56
+ });
57
+ return str || null;
58
+ };
59
+
60
+ var prepareText = function prepareText(text) {
61
+ var txtDom = createElementFromHTML(text);
62
+ var div = document.createElement('div');
63
+ div.innerHTML = "<div separator='true'>".concat(txtDom.innerHTML, '</div>');
64
+ txtDom = div;
65
+ var allDomElements = Array.from(txtDom.querySelectorAll('*'));
66
+
67
+ if (allDomElements.length === 0) {
68
+ return text;
69
+ }
70
+
71
+ return parseParagraphs(txtDom);
72
+ };
73
+
74
+ const generateModel = model => {
75
+ if (!model) return model; // parsing
76
+
77
+ const modelText = prepareText(model.text || '');
78
+ const newTokens = (model.tokens || []).reduce((acc, token = {}) => {
79
+ const tokenText = prepareText((model.text || '').slice(token.start, token.end));
80
+
81
+ if (!tokenText) {
82
+ return [...acc, token];
83
+ }
84
+
85
+ const getStartIndex = start => {
86
+ let length = start;
87
+
88
+ while (length >= 0) {
89
+ let newStartIndex = modelText.slice(length).indexOf(tokenText);
90
+
91
+ if (newStartIndex >= 0) {
92
+ return newStartIndex + length;
93
+ }
94
+
95
+ length--;
96
+ }
97
+
98
+ return 0;
99
+ };
100
+
101
+ const lastToken = acc[acc.length - 1];
102
+ const newStart = getStartIndex(lastToken ? lastToken.end : token.start);
103
+ const newEnd = newStart + tokenText.length;
104
+ return [...acc, _extends({}, token, {
105
+ text: tokenText,
106
+ start: newStart,
107
+ end: newEnd,
108
+ // needed for getScore when tokens position is recalculated
109
+ oldStart: token.start,
110
+ oldEnd: token.end
111
+ })];
112
+ }, []);
113
+ return _extends({}, model, {
114
+ tokens: newTokens,
115
+ text: modelText
116
+ });
117
+ };
118
+ const generateValidationMessage = config => {
119
+ const {
120
+ minTokens,
121
+ maxTokens,
122
+ maxSelections
123
+ } = config;
124
+ const tokensMessage = `\nThere should be at least ${minTokens} ` + (maxTokens ? `and at most ${maxTokens} ` : '') + 'tokens defined.';
125
+ const selectionsMessage = '\nThere should be at least 1 ' + (maxSelections ? `and at most ${maxSelections} ` : '') + 'token' + (maxSelections ? 's' : '') + ' selected.';
126
+ const message = 'Validation requirements:' + tokensMessage + selectionsMessage;
127
+ return message;
128
+ };
129
+
130
+ const {
131
+ Panel,
132
+ toggle,
133
+ radio,
134
+ dropdown
135
+ } = settings;
136
+ const log = debug('@pie-element:select-text:configure');
137
+ class Design extends React.Component {
138
+ constructor(props) {
139
+ super(props);
140
+ this.updateText = debounce(val => {
141
+ this.apply(u => {
142
+ u.text = val;
143
+ u.tokens = [];
144
+ });
145
+ }, 200);
146
+
147
+ this.changeText = event => this.updateText(event.target.value);
148
+
149
+ this.changeTokens = (tokens, mode) => {
150
+ this.apply(u => {
151
+ u.tokens = tokens;
152
+ u.mode = mode;
153
+ const correctTokenCount = tokens.filter(t => t.correct).length;
154
+ const max = isFinite(u.maxSelections) ? u.maxSelections : 0;
155
+ u.maxSelections = Math.max(max, correctTokenCount);
156
+ });
157
+ };
158
+
159
+ this.changeMaxSelections = (event, max) => {
160
+ this.apply(u => u.maxSelections = max);
161
+ };
162
+
163
+ this.apply = fn => {
164
+ const {
165
+ onModelChanged,
166
+ model
167
+ } = this.props;
168
+ const update = cloneDeep(model);
169
+ fn(update);
170
+ onModelChanged(update);
171
+ };
172
+
173
+ this.changeFeedback = feedback => {
174
+ this.apply(u => u.feedback = feedback);
175
+ };
176
+
177
+ this.changePartialScoring = partialScoring => {
178
+ const {
179
+ onModelChanged,
180
+ model
181
+ } = this.props;
182
+ const update = cloneDeep(model);
183
+ update.partialScoring = partialScoring;
184
+ onModelChanged(update);
185
+ };
186
+
187
+ this.onPromptChanged = prompt => {
188
+ const {
189
+ onModelChanged,
190
+ model
191
+ } = this.props;
192
+ const update = cloneDeep(model);
193
+ update.prompt = prompt;
194
+ onModelChanged(update);
195
+ };
196
+
197
+ this.onTeacherInstructionsChanged = teacherInstructions => {
198
+ const {
199
+ onModelChanged,
200
+ model
201
+ } = this.props;
202
+ const update = cloneDeep(model);
203
+ update.teacherInstructions = teacherInstructions;
204
+ onModelChanged(update);
205
+ };
206
+
207
+ this.onRationaleChanged = rationale => {
208
+ const {
209
+ onModelChanged,
210
+ model
211
+ } = this.props;
212
+ onModelChanged(_extends({}, model, {
213
+ rationale
214
+ }));
215
+ };
216
+
217
+ const {
218
+ model: _model
219
+ } = this.props;
220
+ this.state = {
221
+ text: _model && _model.text || ''
222
+ };
223
+ }
224
+
225
+ UNSAFE_componentWillReceiveProps(nProps) {
226
+ const {
227
+ model
228
+ } = nProps;
229
+
230
+ if (model && model.text) {
231
+ this.setState({
232
+ text: model.text
233
+ });
234
+ }
235
+ }
236
+
237
+ render() {
238
+ var _configuration$teache, _configuration$prompt, _configuration$ration;
239
+
240
+ const {
241
+ text: textValue
242
+ } = this.state;
243
+ const {
244
+ classes,
245
+ configuration,
246
+ imageSupport,
247
+ model,
248
+ onConfigurationChanged,
249
+ onModelChanged,
250
+ uploadSoundSupport
251
+ } = this.props;
252
+ const {
253
+ baseInputConfiguration = {},
254
+ correctAnswer = {},
255
+ contentDimensions = {},
256
+ feedback = {},
257
+ highlightChoices = {},
258
+ mode = {},
259
+ partialScoring = {},
260
+ prompt = {},
261
+ rationale = {},
262
+ selectionCount = {},
263
+ selections = {},
264
+ settingsPanelDisabled,
265
+ scoringType = {},
266
+ spellCheck = {},
267
+ studentInstructions = {},
268
+ teacherInstructions = {},
269
+ text = {},
270
+ tokens = {},
271
+ maxImageWidth = {},
272
+ maxImageHeight = {},
273
+ withRubric = {},
274
+ mathMlOptions = {},
275
+ language = {},
276
+ languageChoices = {}
277
+ } = configuration || {};
278
+ const {
279
+ errors,
280
+ extraCSSRules,
281
+ feedbackEnabled,
282
+ promptEnabled,
283
+ rationaleEnabled,
284
+ spellCheckEnabled,
285
+ teacherInstructionsEnabled,
286
+ toolbarEditorPosition
287
+ } = model || {};
288
+ const {
289
+ prompt: promptError,
290
+ rationale: rationaleError,
291
+ selectionsError,
292
+ teacherInstructions: teacherInstructionsError,
293
+ tokensError
294
+ } = errors || {};
295
+ const validationMessage = generateValidationMessage(configuration);
296
+ const defaultImageMaxWidth = maxImageWidth && maxImageWidth.prompt;
297
+ const defaultImageMaxHeight = maxImageHeight && maxImageHeight.prompt;
298
+ let {
299
+ tokens: tokensModel
300
+ } = model;
301
+ tokensModel = tokensModel || [];
302
+ const toolbarOpts = {
303
+ position: toolbarEditorPosition === 'top' ? 'top' : 'bottom'
304
+ };
305
+ log('[render] maxSelections:', model.maxSelections);
306
+ const panelSettings = {
307
+ partialScoring: partialScoring.settings && toggle(partialScoring.label),
308
+ highlightChoices: highlightChoices.settings && toggle(highlightChoices.label),
309
+ feedbackEnabled: feedback.settings && toggle(feedback.label),
310
+ 'language.enabled': language.settings && toggle(language.label, true),
311
+ language: language.settings && language.enabled && dropdown(languageChoices.label, languageChoices.options)
312
+ };
313
+ const panelProperties = {
314
+ teacherInstructionsEnabled: teacherInstructions.settings && toggle(teacherInstructions.label),
315
+ studentInstructionsEnabled: studentInstructions.settings && toggle(studentInstructions.label),
316
+ promptEnabled: prompt.settings && toggle(prompt.label),
317
+ rationaleEnabled: rationale.settings && toggle(rationale.label),
318
+ spellCheckEnabled: spellCheck.settings && toggle(spellCheck.label),
319
+ scoringType: scoringType.settings && radio(scoringType.label, ['auto', 'rubric']),
320
+ rubricEnabled: (withRubric == null ? void 0 : withRubric.settings) && toggle(withRubric == null ? void 0 : withRubric.label)
321
+ };
322
+
323
+ const getPluginProps = (props = {}) => _extends({}, baseInputConfiguration, props);
324
+
325
+ return /*#__PURE__*/React.createElement(layout.ConfigLayout, {
326
+ extraCSSRules: extraCSSRules,
327
+ dimensions: contentDimensions,
328
+ hideSettings: settingsPanelDisabled,
329
+ settings: /*#__PURE__*/React.createElement(Panel, {
330
+ model: model,
331
+ configuration: configuration,
332
+ onChangeModel: model => onModelChanged(model),
333
+ onChangeConfiguration: onConfigurationChanged,
334
+ groups: {
335
+ Settings: panelSettings,
336
+ Properties: panelProperties
337
+ }
338
+ })
339
+ }, teacherInstructionsEnabled && /*#__PURE__*/React.createElement(InputContainer, {
340
+ label: teacherInstructions.label,
341
+ className: classes.promptHolder
342
+ }, /*#__PURE__*/React.createElement(EditableHtml, {
343
+ className: classes.prompt,
344
+ markup: model.teacherInstructions || '',
345
+ onChange: this.onTeacherInstructionsChanged,
346
+ imageSupport: imageSupport,
347
+ nonEmpty: false,
348
+ error: teacherInstructionsError,
349
+ toolbarOpts: toolbarOpts,
350
+ pluginProps: getPluginProps(configuration == null ? void 0 : (_configuration$teache = configuration.teacherInstructions) == null ? void 0 : _configuration$teache.inputConfiguration),
351
+ spellCheck: spellCheckEnabled,
352
+ maxImageWidth: maxImageWidth && maxImageWidth.teacherInstructions || defaultImageMaxWidth,
353
+ maxImageHeight: maxImageHeight && maxImageHeight.teacherInstructions || defaultImageMaxHeight,
354
+ uploadSoundSupport: uploadSoundSupport,
355
+ languageCharactersProps: [{
356
+ language: 'spanish'
357
+ }, {
358
+ language: 'special'
359
+ }],
360
+ mathMlOptions: mathMlOptions
361
+ }), teacherInstructionsError && /*#__PURE__*/React.createElement("div", {
362
+ className: classes.errorText
363
+ }, teacherInstructionsError)), promptEnabled && /*#__PURE__*/React.createElement(InputContainer, {
364
+ label: prompt.label || '',
365
+ className: classes.promptHolder
366
+ }, /*#__PURE__*/React.createElement(EditableHtml, {
367
+ className: classes.prompt,
368
+ markup: model.prompt,
369
+ onChange: this.onPromptChanged,
370
+ imageSupport: imageSupport,
371
+ error: promptError,
372
+ toolbarOpts: toolbarOpts,
373
+ pluginProps: getPluginProps(configuration == null ? void 0 : (_configuration$prompt = configuration.prompt) == null ? void 0 : _configuration$prompt.inputConfiguration),
374
+ spellCheck: spellCheckEnabled,
375
+ maxImageWidth: defaultImageMaxWidth,
376
+ maxImageHeight: defaultImageMaxHeight,
377
+ uploadSoundSupport: uploadSoundSupport,
378
+ languageCharactersProps: [{
379
+ language: 'spanish'
380
+ }, {
381
+ language: 'special'
382
+ }],
383
+ mathMlOptions: mathMlOptions
384
+ }), promptError && /*#__PURE__*/React.createElement("div", {
385
+ className: classes.errorText
386
+ }, promptError)), text.settings && /*#__PURE__*/React.createElement(InputContainer, {
387
+ label: text.label || '',
388
+ className: classes.promptHolder
389
+ }, /*#__PURE__*/React.createElement(TextField, {
390
+ className: classes.input,
391
+ multiline: true,
392
+ defaultValue: textValue,
393
+ onChange: this.changeText,
394
+ spellCheck: spellCheckEnabled
395
+ })), tokens.settings && /*#__PURE__*/React.createElement(InputContainer, {
396
+ label: tokens.label || '',
397
+ className: classes.tokenizerContainer
398
+ }, /*#__PURE__*/React.createElement(Tooltip, {
399
+ classes: {
400
+ tooltip: classes.tooltip
401
+ },
402
+ disableFocusListener: true,
403
+ disableTouchListener: true,
404
+ placement: 'right',
405
+ title: validationMessage
406
+ }, /*#__PURE__*/React.createElement(Info, {
407
+ fontSize: 'small',
408
+ color: 'primary',
409
+ style: {
410
+ position: 'absolute',
411
+ left: '48px',
412
+ top: '-3px'
413
+ }
414
+ })), /*#__PURE__*/React.createElement(Tokenizer, {
415
+ className: classes.tokenizer,
416
+ text: model.text,
417
+ tokens: tokensModel,
418
+ onChange: this.changeTokens
419
+ })), tokensError && /*#__PURE__*/React.createElement("div", {
420
+ className: classes.errorText
421
+ }, tokensError), selectionsError && /*#__PURE__*/React.createElement("div", {
422
+ className: classes.errorText
423
+ }, selectionsError), /*#__PURE__*/React.createElement("div", {
424
+ className: classes.tokensDetails
425
+ }, mode.settings && /*#__PURE__*/React.createElement(Chip, {
426
+ label: `${mode.label}: ${model.mode ? model.mode : 'None'}`,
427
+ className: classes.chip
428
+ }), selections.settings && /*#__PURE__*/React.createElement(Chip, {
429
+ label: `${selections.label}: ${tokensModel.length}`,
430
+ className: classes.chip
431
+ }), correctAnswer.settings && /*#__PURE__*/React.createElement(Chip, {
432
+ label: `${correctAnswer.label}: ${tokensModel.filter(t => t.correct).length}`,
433
+ className: classes.chip
434
+ }), selectionCount.settings && /*#__PURE__*/React.createElement(NumberTextField, {
435
+ min: tokensModel.filter(t => t.correct).length || 0,
436
+ label: `${selectionCount.label} (0:any)`,
437
+ max: tokensModel.length,
438
+ value: model.maxSelections,
439
+ onChange: this.changeMaxSelections,
440
+ className: classes.numberField
441
+ })), rationaleEnabled && /*#__PURE__*/React.createElement(InputContainer, {
442
+ label: rationale.label || '',
443
+ className: classes.promptHolder
444
+ }, /*#__PURE__*/React.createElement(EditableHtml, {
445
+ className: classes.prompt,
446
+ markup: model.rationale || '',
447
+ onChange: this.onRationaleChanged,
448
+ imageSupport: imageSupport,
449
+ error: rationaleError,
450
+ toolbarOpts: toolbarOpts,
451
+ pluginProps: getPluginProps(configuration == null ? void 0 : (_configuration$ration = configuration.rationale) == null ? void 0 : _configuration$ration.inputConfiguration),
452
+ spellCheck: spellCheckEnabled,
453
+ maxImageWidth: maxImageWidth && maxImageWidth.rationale || defaultImageMaxWidth,
454
+ maxImageHeight: maxImageHeight && maxImageHeight.rationale || defaultImageMaxHeight,
455
+ uploadSoundSupport: uploadSoundSupport,
456
+ languageCharactersProps: [{
457
+ language: 'spanish'
458
+ }, {
459
+ language: 'special'
460
+ }],
461
+ mathMlOptions: mathMlOptions
462
+ }), rationaleError && /*#__PURE__*/React.createElement("div", {
463
+ className: classes.errorText
464
+ }, rationaleError)), feedbackEnabled && /*#__PURE__*/React.createElement(FeedbackConfig, {
465
+ feedback: model.feedback,
466
+ onChange: this.changeFeedback,
467
+ toolbarOpts: toolbarOpts
468
+ }));
469
+ }
470
+
471
+ }
472
+ Design.propTypes = {
473
+ model: PropTypes.object.isRequired,
474
+ configuration: PropTypes.object.isRequired,
475
+ classes: PropTypes.object.isRequired,
476
+ onModelChanged: PropTypes.func.isRequired,
477
+ onConfigurationChanged: PropTypes.func.isRequired,
478
+ imageSupport: PropTypes.shape({
479
+ add: PropTypes.func.isRequired,
480
+ delete: PropTypes.func.isRequired
481
+ }),
482
+ uploadSoundSupport: PropTypes.object
483
+ };
484
+ Design.defaultProps = {};
485
+ var Main = withStyles(theme => ({
486
+ tokenizerContainer: {
487
+ paddingRight: 0,
488
+ marginRight: 0,
489
+ '&:after': {
490
+ position: 'absolute',
491
+ bottom: 0,
492
+ left: 0,
493
+ right: 0,
494
+ height: '1px',
495
+ content: '""',
496
+ backgroundColor: theme.palette.primary.main
497
+ },
498
+ marginBottom: theme.spacing.unit
499
+ },
500
+ chip: {
501
+ marginTop: theme.spacing.unit / 2,
502
+ marginRight: theme.spacing.unit * 2
503
+ },
504
+ input: {
505
+ width: '100%'
506
+ },
507
+ tokenizer: {
508
+ marginTop: theme.spacing.unit * 2
509
+ },
510
+ mainOpts: {
511
+ width: '100%',
512
+ justifyContent: 'space-between',
513
+ display: 'flex',
514
+ alignItems: 'baseline'
515
+ },
516
+ promptHolder: {
517
+ width: '100%',
518
+ paddingTop: theme.spacing.unit * 2,
519
+ marginBottom: theme.spacing.unit * 2
520
+ },
521
+ tokensDetails: {
522
+ display: 'flex',
523
+ alignItems: 'center',
524
+ flexWrap: 'wrap',
525
+ marginBottom: theme.spacing.unit * 2.5
526
+ },
527
+ numberField: {
528
+ width: '180px',
529
+ margin: `${theme.spacing.unit / 2}px auto 0`
530
+ },
531
+ tooltip: {
532
+ fontSize: theme.typography.fontSize - 2,
533
+ whiteSpace: 'pre',
534
+ maxWidth: '500px'
535
+ },
536
+ errorText: {
537
+ fontSize: theme.typography.fontSize - 2,
538
+ color: theme.palette.error.main,
539
+ paddingTop: theme.spacing.unit
540
+ }
541
+ }))(Design);
542
+
543
+ var defaultValues = {
544
+ model: {
545
+ feedbackEnabled: false,
546
+ highlightChoices: false,
547
+ maxSelections: 0,
548
+ mode: 'sentence',
549
+ partialScoring: false,
550
+ prompt: '',
551
+ promptEnabled: true,
552
+ rationale: '',
553
+ rationaleEnabled: true,
554
+ scoringType: 'auto',
555
+ studentInstructionsEnabled: true,
556
+ teacherInstructions: '',
557
+ teacherInstructionsEnabled: true,
558
+ text: '',
559
+ tokens: [],
560
+ toolbarEditorPosition: 'bottom'
561
+ },
562
+ configuration: {
563
+ baseInputConfiguration: {
564
+ audio: {
565
+ disabled: false
566
+ },
567
+ video: {
568
+ disabled: false
569
+ },
570
+ image: {
571
+ disabled: false
572
+ },
573
+ textAlign: {
574
+ disabled: true
575
+ },
576
+ showParagraphs: {
577
+ disabled: false
578
+ },
579
+ separateParagraphs: {
580
+ disabled: true
581
+ }
582
+ },
583
+ selectionCount: {
584
+ settings: true,
585
+ label: 'Selection count'
586
+ },
587
+ correctAnswer: {
588
+ settings: true,
589
+ label: 'Correct Answers'
590
+ },
591
+ selections: {
592
+ settings: true,
593
+ label: 'Selections Available'
594
+ },
595
+ highlightChoices: {
596
+ settings: true,
597
+ label: 'Highlight choices'
598
+ },
599
+ rationale: {
600
+ settings: true,
601
+ label: 'Rationale',
602
+ inputConfiguration: {
603
+ audio: {
604
+ disabled: false
605
+ },
606
+ video: {
607
+ disabled: false
608
+ },
609
+ image: {
610
+ disabled: false
611
+ }
612
+ },
613
+ required: false
614
+ },
615
+ scoringType: {
616
+ settings: false,
617
+ label: 'Scoring Type'
618
+ },
619
+ studentInstructions: {
620
+ settings: false,
621
+ label: 'Student Instructions'
622
+ },
623
+ teacherInstructions: {
624
+ settings: true,
625
+ label: 'Teacher Instructions',
626
+ inputConfiguration: {
627
+ audio: {
628
+ disabled: false
629
+ },
630
+ video: {
631
+ disabled: false
632
+ },
633
+ image: {
634
+ disabled: false
635
+ }
636
+ },
637
+ required: false
638
+ },
639
+ prompt: {
640
+ label: 'Prompt',
641
+ settings: true,
642
+ inputConfiguration: {
643
+ audio: {
644
+ disabled: false
645
+ },
646
+ video: {
647
+ disabled: false
648
+ },
649
+ image: {
650
+ disabled: false
651
+ }
652
+ },
653
+ required: false
654
+ },
655
+ text: {
656
+ settings: true,
657
+ label: 'Content'
658
+ },
659
+ tokens: {
660
+ settings: true,
661
+ label: 'Tokens'
662
+ },
663
+ feedback: {
664
+ settings: true,
665
+ label: 'Feedback'
666
+ },
667
+ spellCheck: {
668
+ label: 'Spellcheck',
669
+ settings: false,
670
+ enabled: true
671
+ },
672
+ partialScoring: {
673
+ settings: false,
674
+ label: 'Allow Partial Scoring'
675
+ },
676
+ mode: {
677
+ settings: true,
678
+ label: 'Mode'
679
+ },
680
+ minTokens: 2,
681
+ maxImageWidth: {
682
+ teacherInstructions: 300,
683
+ prompt: 300,
684
+ rationale: 300
685
+ },
686
+ maxImageHeight: {
687
+ teacherInstructions: 300,
688
+ prompt: 300,
689
+ rationale: 300
690
+ },
691
+ withRubric: {
692
+ settings: false,
693
+ label: 'Add Rubric'
694
+ },
695
+ mathMlOptions: {
696
+ mmlOutput: false,
697
+ mmlEditing: false
698
+ },
699
+ language: {
700
+ settings: false,
701
+ label: 'Specify Language',
702
+ enabled: false
703
+ },
704
+ languageChoices: {
705
+ label: 'Language Choices',
706
+ options: []
707
+ }
708
+ }
709
+ };
710
+
711
+ class SelectTextConfigure extends HTMLElement {
712
+ constructor() {
713
+ super();
714
+ this._model = SelectTextConfigure.createDefaultModel();
715
+ this._configuration = defaultValues.configuration;
716
+ }
717
+
718
+ set model(m) {
719
+ this._model = SelectTextConfigure.createDefaultModel(m);
720
+ this.render();
721
+ }
722
+
723
+ set configuration(c) {
724
+ var _newConfiguration$lan;
725
+
726
+ const newConfiguration = _extends({}, defaultValues.configuration, c);
727
+
728
+ this._configuration = newConfiguration; // if language:enabled is true, then the corresponding default item model should include a language value;
729
+ // if it is false, then the language field should be omitted from the item model.
730
+ // if a default item model includes a language value (e.g., en_US) and the corresponding authoring view settings have language:settings = true,
731
+ // then (a) language:enabled should also be true, and (b) that default language value should be represented in languageChoices[] (as a key).
732
+
733
+ if (newConfiguration != null && (_newConfiguration$lan = newConfiguration.language) != null && _newConfiguration$lan.enabled) {
734
+ var _newConfiguration$lan2, _newConfiguration$lan3;
735
+
736
+ if (newConfiguration != null && (_newConfiguration$lan2 = newConfiguration.languageChoices) != null && (_newConfiguration$lan3 = _newConfiguration$lan2.options) != null && _newConfiguration$lan3.length) {
737
+ this._model.language = newConfiguration == null ? void 0 : newConfiguration.languageChoices.options[0].value;
738
+ }
739
+ } else if (newConfiguration.language.settings && this._model.language) {
740
+ this._configuration.language.enabled = true;
741
+
742
+ if (!this._configuration.languageChoices.options || !this._configuration.languageChoices.options.length) {
743
+ this._configuration.languageChoices.options = [];
744
+ } // check if the language is already included in the languageChoices.options array
745
+ // and if not, then add it.
746
+
747
+
748
+ if (!this._configuration.languageChoices.options.find(option => option.value === this._model.language)) {
749
+ this._configuration.languageChoices.options.push({
750
+ value: this._model.language,
751
+ label: this._model.language
752
+ });
753
+ }
754
+ } else {
755
+ delete this._model.language;
756
+ }
757
+
758
+ this.render();
759
+ }
760
+
761
+ connectedCallback() {
762
+ this.render();
763
+ }
764
+
765
+ modelChanged(m) {
766
+ this._model = m;
767
+ this.dispatchEvent(new ModelUpdatedEvent(this._model), true);
768
+ this.render();
769
+ }
770
+
771
+ onConfigurationChanged(c) {
772
+ this._configuration = c;
773
+
774
+ if (this._model) {
775
+ this.dispatchEvent(new ModelUpdatedEvent(this._model), false);
776
+ }
777
+
778
+ this.render();
779
+ }
780
+ /**
781
+ *
782
+ * @param {done, progress, file} handler
783
+ */
784
+
785
+
786
+ insertImage(handler) {
787
+ this.dispatchEvent(new InsertImageEvent(handler));
788
+ }
789
+
790
+ onDeleteImage(src, done) {
791
+ this.dispatchEvent(new DeleteImageEvent(src, done));
792
+ }
793
+
794
+ insertSound(handler) {
795
+ this.dispatchEvent(new InsertSoundEvent(handler));
796
+ }
797
+
798
+ onDeleteSound(src, done) {
799
+ this.dispatchEvent(new DeleteSoundEvent(src, done));
800
+ }
801
+
802
+ render() {
803
+ if (this._model) {
804
+ const el = /*#__PURE__*/React.createElement(Main, {
805
+ model: this._model,
806
+ configuration: this._configuration,
807
+ onModelChanged: this.modelChanged.bind(this),
808
+ onConfigurationChanged: this.onConfigurationChanged.bind(this),
809
+ imageSupport: {
810
+ add: this.insertImage.bind(this),
811
+ delete: this.onDeleteImage.bind(this)
812
+ },
813
+ uploadSoundSupport: {
814
+ add: this.insertSound.bind(this),
815
+ delete: this.onDeleteSound.bind(this)
816
+ }
817
+ });
818
+ ReactDOM.render(el, this);
819
+ }
820
+ }
821
+
822
+ }
823
+
824
+ SelectTextConfigure.createDefaultModel = (model = {}) => {
825
+ const newModel = _extends({}, defaultValues.model, model);
826
+
827
+ return generateModel(newModel);
828
+ };
829
+
830
+ export { SelectTextConfigure as default };
831
+ //# sourceMappingURL=configure.js.map