@pie-element/math-templated 7.1.1-next.12 → 7.1.2
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/CHANGELOG.json +1 -0
- package/CHANGELOG.md +1144 -0
- package/LICENSE.md +5 -0
- package/README.md +0 -0
- package/configure/CHANGELOG.json +1 -0
- package/configure/CHANGELOG.md +1021 -0
- package/configure/lib/defaults.js +172 -0
- package/configure/lib/defaults.js.map +1 -0
- package/configure/lib/design.js +546 -0
- package/configure/lib/design.js.map +1 -0
- package/configure/lib/index.js +169 -0
- package/configure/lib/index.js.map +1 -0
- package/configure/lib/markupUtils.js +39 -0
- package/configure/lib/markupUtils.js.map +1 -0
- package/configure/lib/response.js +394 -0
- package/configure/lib/response.js.map +1 -0
- package/configure/lib/utils.js +15 -0
- package/configure/lib/utils.js.map +1 -0
- package/configure/package.json +26 -0
- package/controller/CHANGELOG.json +1 -0
- package/controller/CHANGELOG.md +874 -0
- package/controller/lib/defaults.js +28 -0
- package/controller/lib/defaults.js.map +1 -0
- package/controller/lib/index.js +360 -0
- package/controller/lib/index.js.map +1 -0
- package/controller/package.json +17 -0
- package/docs/config-schema.json +2251 -0
- package/docs/config-schema.json.md +1658 -0
- package/docs/demo/config.js +8 -0
- package/docs/demo/generate.js +42 -0
- package/docs/demo/index.html +1 -0
- package/docs/demo/session.js +14 -0
- package/docs/pie-schema.json +1231 -0
- package/docs/pie-schema.json.md +894 -0
- package/lib/index.js +76 -0
- package/lib/index.js.map +1 -0
- package/lib/main.js +877 -0
- package/lib/main.js.map +1 -0
- package/lib/print.js +88 -0
- package/lib/print.js.map +1 -0
- package/module/configure.js +1 -0
- package/module/controller.js +3711 -0
- package/module/demo.js +67 -0
- package/module/element.js +1 -0
- package/module/index.html +21 -0
- package/module/manifest.json +22 -0
- package/module/print-demo.js +105 -0
- package/module/print.html +18 -0
- package/module/print.js +1 -0
- package/package.json +22 -93
- package/configure.js +0 -2
- package/controller.js +0 -1
- package/dist/author/defaults.d.ts +0 -173
- package/dist/author/defaults.js +0 -123
- package/dist/author/design.d.ts +0 -35
- package/dist/author/design.js +0 -360
- package/dist/author/index.d.ts +0 -42
- package/dist/author/index.js +0 -97
- package/dist/author/markupUtils.d.ts +0 -11
- package/dist/author/markupUtils.js +0 -10
- package/dist/author/response.d.ts +0 -41
- package/dist/author/response.js +0 -238
- package/dist/author/utils.d.ts +0 -9
- package/dist/author/utils.js +0 -7
- package/dist/browser/author/index.js +0 -31954
- package/dist/browser/author/index.js.map +0 -1
- package/dist/browser/browser-DJA4OL8j.js +0 -331
- package/dist/browser/browser-DJA4OL8j.js.map +0 -1
- package/dist/browser/controller/index.js +0 -37731
- package/dist/browser/controller/index.js.map +0 -1
- package/dist/browser/delivery/index.js +0 -81
- package/dist/browser/delivery/index.js.map +0 -1
- package/dist/browser/dist-Csid0rBE.js +0 -17046
- package/dist/browser/dist-Csid0rBE.js.map +0 -1
- package/dist/browser/dist-D9ARZhQk.js +0 -1426
- package/dist/browser/dist-D9ARZhQk.js.map +0 -1
- package/dist/browser/main-I_wWeaur.js +0 -1274
- package/dist/browser/main-I_wWeaur.js.map +0 -1
- package/dist/browser/math-templated.css +0 -2
- package/dist/browser/print/index.js +0 -47
- package/dist/browser/print/index.js.map +0 -1
- package/dist/controller/defaults.d.ts +0 -29
- package/dist/controller/defaults.js +0 -23
- package/dist/controller/index.d.ts +0 -45
- package/dist/controller/index.js +0 -154
- package/dist/delivery/index.d.ts +0 -20
- package/dist/delivery/index.js +0 -51
- package/dist/delivery/main.d.ts +0 -40
- package/dist/delivery/main.js +0 -492
- package/dist/index.d.ts +0 -1
- package/dist/index.iife.d.ts +0 -8
- package/dist/index.iife.js +0 -205
- package/dist/index.js +0 -2
- package/dist/math-templated.css +0 -2
- package/dist/print/index.d.ts +0 -15
- package/dist/print/index.js +0 -47
- package/dist/runtime-support.d.ts +0 -12
- package/dist/runtime-support.js +0 -12
package/lib/main.js
ADDED
|
@@ -0,0 +1,877 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = exports.Main = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _react = _interopRequireDefault(require("react"));
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
var _lodashEs = require("lodash-es");
|
|
12
|
+
var _styles = require("@mui/material/styles");
|
|
13
|
+
var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip"));
|
|
14
|
+
var _mathInput = require("@pie-lib/math-input");
|
|
15
|
+
var _renderUi = require("@pie-lib/render-ui");
|
|
16
|
+
var _mathRendering = require("@pie-lib/math-rendering");
|
|
17
|
+
var _maskMarkup = require("@pie-lib/mask-markup");
|
|
18
|
+
var _correctAnswerToggle = _interopRequireDefault(require("@pie-lib/correct-answer-toggle"));
|
|
19
|
+
var _reactDom = _interopRequireDefault(require("react-dom"));
|
|
20
|
+
const StyledUiLayout = (0, _styles.styled)(_renderUi.UiLayout)({
|
|
21
|
+
color: _renderUi.color.text(),
|
|
22
|
+
backgroundColor: _renderUi.color.background(),
|
|
23
|
+
display: 'inline-block'
|
|
24
|
+
});
|
|
25
|
+
const MainContainer = (0, _styles.styled)('div')({
|
|
26
|
+
width: '100%',
|
|
27
|
+
position: 'relative',
|
|
28
|
+
backgroundColor: _renderUi.color.background(),
|
|
29
|
+
color: _renderUi.color.text()
|
|
30
|
+
});
|
|
31
|
+
const PromptContainer = (0, _styles.styled)('div')(({
|
|
32
|
+
theme
|
|
33
|
+
}) => ({
|
|
34
|
+
marginBottom: theme.spacing(2)
|
|
35
|
+
}));
|
|
36
|
+
const CollapsibleContainer = (0, _styles.styled)('div')(({
|
|
37
|
+
theme
|
|
38
|
+
}) => ({
|
|
39
|
+
marginBottom: theme.spacing(2)
|
|
40
|
+
}));
|
|
41
|
+
const InputAndKeypadContainer = (0, _styles.styled)('div')({
|
|
42
|
+
position: 'relative',
|
|
43
|
+
'& > div > div': {
|
|
44
|
+
display: 'flex',
|
|
45
|
+
alignItems: 'baseline',
|
|
46
|
+
flexWrap: 'wrap'
|
|
47
|
+
},
|
|
48
|
+
'& .mq-overarrow-inner': {
|
|
49
|
+
border: 'none !important',
|
|
50
|
+
padding: '0 !important'
|
|
51
|
+
},
|
|
52
|
+
'& .mq-overarrow-inner-right': {
|
|
53
|
+
display: 'none !important'
|
|
54
|
+
},
|
|
55
|
+
'& .mq-overarrow-inner-left': {
|
|
56
|
+
display: 'none !important'
|
|
57
|
+
},
|
|
58
|
+
'& .mq-overarrow.mq-arrow-both': {
|
|
59
|
+
minWidth: '1.23em',
|
|
60
|
+
'& *': {
|
|
61
|
+
lineHeight: '1 !important'
|
|
62
|
+
},
|
|
63
|
+
'&:before': {
|
|
64
|
+
top: '-0.4em',
|
|
65
|
+
left: '-1px'
|
|
66
|
+
},
|
|
67
|
+
'&:after': {
|
|
68
|
+
top: '-2.4em',
|
|
69
|
+
right: '-1px'
|
|
70
|
+
},
|
|
71
|
+
'&.mq-empty:after': {
|
|
72
|
+
top: '-0.45em'
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
'& .mq-overarrow.mq-arrow-right': {
|
|
76
|
+
'&:before': {
|
|
77
|
+
top: '-0.4em',
|
|
78
|
+
right: '-1px'
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
'& .mq-longdiv-inner': {
|
|
82
|
+
borderTop: '1px solid !important',
|
|
83
|
+
paddingTop: '1.5px !important'
|
|
84
|
+
},
|
|
85
|
+
'& .mq-parallelogram': {
|
|
86
|
+
lineHeight: 0.85
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
const Expression = (0, _styles.styled)('div')(({
|
|
90
|
+
theme,
|
|
91
|
+
$incorrect,
|
|
92
|
+
$correct,
|
|
93
|
+
$showCorrectness,
|
|
94
|
+
$correctAnswerShown
|
|
95
|
+
}) => ({
|
|
96
|
+
maxWidth: 'fit-content',
|
|
97
|
+
...($incorrect && {
|
|
98
|
+
borderColor: `${_renderUi.color.incorrect()} !important`
|
|
99
|
+
}),
|
|
100
|
+
...($correct && {
|
|
101
|
+
borderColor: `${_renderUi.color.correct()} !important`
|
|
102
|
+
}),
|
|
103
|
+
...($showCorrectness && {
|
|
104
|
+
border: '2px solid'
|
|
105
|
+
}),
|
|
106
|
+
...($correctAnswerShown && {
|
|
107
|
+
padding: theme.spacing(1),
|
|
108
|
+
letterSpacing: '0.5px'
|
|
109
|
+
}),
|
|
110
|
+
'& > .mq-math-mode': {
|
|
111
|
+
'& > .mq-root-block': {
|
|
112
|
+
'& > .mq-editable-field': {
|
|
113
|
+
minWidth: '10px',
|
|
114
|
+
padding: theme.spacing(0.25)
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
'& sup': {
|
|
118
|
+
top: 0
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}));
|
|
122
|
+
const StyledStatic = (0, _styles.styled)(_mathInput.mq.Static)({
|
|
123
|
+
'& > .mq-root-block': {
|
|
124
|
+
'& > .mq-editable-field': {
|
|
125
|
+
borderColor: _renderUi.color.text()
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Tooltip styling is handled via slotProps, no need for styled component
|
|
131
|
+
|
|
132
|
+
const ResponseContainer = (0, _styles.styled)('div')(({
|
|
133
|
+
theme
|
|
134
|
+
}) => ({
|
|
135
|
+
zIndex: 10,
|
|
136
|
+
minWidth: '400px',
|
|
137
|
+
marginTop: theme.spacing(2)
|
|
138
|
+
}));
|
|
139
|
+
const PrintContainer = (0, _styles.styled)('div')(({
|
|
140
|
+
theme
|
|
141
|
+
}) => ({
|
|
142
|
+
marginBottom: theme.spacing(1),
|
|
143
|
+
pointerEvents: 'none'
|
|
144
|
+
}));
|
|
145
|
+
const SrOnly = (0, _styles.styled)('h2')({
|
|
146
|
+
position: 'absolute',
|
|
147
|
+
left: '-10000px',
|
|
148
|
+
top: 'auto',
|
|
149
|
+
width: '1px',
|
|
150
|
+
height: '1px',
|
|
151
|
+
overflow: 'hidden'
|
|
152
|
+
});
|
|
153
|
+
const Note = (0, _styles.styled)('div')(({
|
|
154
|
+
theme
|
|
155
|
+
}) => ({
|
|
156
|
+
marginBottom: theme.spacing(2)
|
|
157
|
+
}));
|
|
158
|
+
const StyledToggle = (0, _styles.styled)(_correctAnswerToggle.default)(({
|
|
159
|
+
theme
|
|
160
|
+
}) => ({
|
|
161
|
+
color: _renderUi.color.text(),
|
|
162
|
+
marginBottom: theme.spacing(2)
|
|
163
|
+
}));
|
|
164
|
+
|
|
165
|
+
// CSS for classes used in HTML strings and classList operations
|
|
166
|
+
if (typeof document !== 'undefined') {
|
|
167
|
+
const styleId = 'math-templated-main-styles';
|
|
168
|
+
if (!document.getElementById(styleId)) {
|
|
169
|
+
const style = document.createElement('style');
|
|
170
|
+
style.id = styleId;
|
|
171
|
+
style.textContent = `
|
|
172
|
+
.block-container {
|
|
173
|
+
margin: 8px !important;
|
|
174
|
+
display: inline-flex;
|
|
175
|
+
border: 2px solid grey !important;
|
|
176
|
+
}
|
|
177
|
+
.block-response {
|
|
178
|
+
flex: 2;
|
|
179
|
+
color: grey;
|
|
180
|
+
background: rgba(0, 0, 0, 0.04);
|
|
181
|
+
font-size: 0.8rem !important;
|
|
182
|
+
padding: 4px !important;
|
|
183
|
+
display: flex;
|
|
184
|
+
align-items: center;
|
|
185
|
+
justify-content: center;
|
|
186
|
+
border-right: 2px solid #bdbdbd !important;
|
|
187
|
+
}
|
|
188
|
+
.block-math {
|
|
189
|
+
color: ${_renderUi.color.text()};
|
|
190
|
+
background-color: ${_renderUi.color.background()};
|
|
191
|
+
padding: 4px !important;
|
|
192
|
+
display: flex;
|
|
193
|
+
align-items: center;
|
|
194
|
+
justify-content: center;
|
|
195
|
+
flex: 8;
|
|
196
|
+
}
|
|
197
|
+
.block-math > .mq-math-mode > .mq-hasCursor > .mq-cursor {
|
|
198
|
+
display: none;
|
|
199
|
+
}
|
|
200
|
+
.correct {
|
|
201
|
+
border-color: ${_renderUi.color.correct()} !important;
|
|
202
|
+
}
|
|
203
|
+
.incorrect {
|
|
204
|
+
border-color: ${_renderUi.color.incorrect()} !important;
|
|
205
|
+
}
|
|
206
|
+
`;
|
|
207
|
+
document.head.appendChild(style);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
let registered = false;
|
|
211
|
+
|
|
212
|
+
// Define a regex pattern to match {{number}}
|
|
213
|
+
const REGEX = /(\{\{\d+\}\})/gm;
|
|
214
|
+
const DEFAULT_KEYPAD_VARIANT = 6;
|
|
215
|
+
const KEYPAD_VIEWPORT_PADDING = 8;
|
|
216
|
+
|
|
217
|
+
// !!! If you're using Chrome but have selected the "iPad" device in Chrome Developer Tools, the navigator.userAgent string may still report as
|
|
218
|
+
// Safari because Chrome on iOS actually uses the Safari rendering engine under the hood due to Apple's restrictions on third-party browser engines.
|
|
219
|
+
// When you select the "iPad" device in Chrome Developer Tools, you're essentially emulating the behavior of Safari on an iPad, including the user agent string.
|
|
220
|
+
// Therefore, even though you're using Chrome, the user agent string will resemble that of Safari on an iPad.
|
|
221
|
+
// Since the regular expression /^((?!chrome|android).)*safari/i checks for the presence of "safari" in the user agent string while excluding "chrome" and "android",
|
|
222
|
+
// it will return true in this case because "safari" is present in the user agent string emulated by Chrome when in iPad mode.
|
|
223
|
+
const IS_SAFARI = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
224
|
+
function generateAdditionalKeys(keyData = []) {
|
|
225
|
+
return keyData.map(key => ({
|
|
226
|
+
name: key,
|
|
227
|
+
latex: key,
|
|
228
|
+
write: key,
|
|
229
|
+
label: key
|
|
230
|
+
}));
|
|
231
|
+
}
|
|
232
|
+
function getKeyPadWidth(additionalKeys = [], equationEditor) {
|
|
233
|
+
return Math.floor(additionalKeys.length / 5) * 30 + (equationEditor === 'miscellaneous' ? 600 : 500);
|
|
234
|
+
}
|
|
235
|
+
function splitByParts(text) {
|
|
236
|
+
// Use the regex pattern to split the text
|
|
237
|
+
const parts = text.split(REGEX);
|
|
238
|
+
// Filter out empty strings that might result from splitting
|
|
239
|
+
return parts.filter(part => part);
|
|
240
|
+
}
|
|
241
|
+
function prepareForStatic(model, state) {
|
|
242
|
+
const {
|
|
243
|
+
responses,
|
|
244
|
+
disabled,
|
|
245
|
+
markup,
|
|
246
|
+
printMode,
|
|
247
|
+
alwaysShowCorrect
|
|
248
|
+
} = model || {};
|
|
249
|
+
if (markup) {
|
|
250
|
+
if (state.showCorrect) {
|
|
251
|
+
return Object.keys(responses || {}).reduce((acc, responseKey) => {
|
|
252
|
+
acc[responseKey] = responses?.[responseKey]?.answer;
|
|
253
|
+
return acc;
|
|
254
|
+
}, {});
|
|
255
|
+
}
|
|
256
|
+
const splitted = splitByParts(markup);
|
|
257
|
+
return splitted.reduce((acc, split) => {
|
|
258
|
+
if (split.match(REGEX)) {
|
|
259
|
+
const responseKey = Main.getResponseKey(split);
|
|
260
|
+
const answer = state.session.answers[`r${responseKey}`];
|
|
261
|
+
if (printMode && !alwaysShowCorrect) {
|
|
262
|
+
const blankSpace = '\\ \\ '.repeat(30) + '\\embed{newLine}[] ';
|
|
263
|
+
return {
|
|
264
|
+
...acc,
|
|
265
|
+
[responseKey]: `\\MathQuillMathField[r${responseKey}]{${blankSpace.repeat(3)}}`
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (disabled) {
|
|
269
|
+
return {
|
|
270
|
+
...acc,
|
|
271
|
+
[responseKey]: `\\embed{answerBlock}[r${responseKey}]`
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
...acc,
|
|
276
|
+
[responseKey]: `\\MathQuillMathField[r${responseKey}]{${answer && answer.value || ''}}`
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
return acc;
|
|
280
|
+
}, {});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Popper.js v2 modifier that implements precise horizontal placement:
|
|
286
|
+
*
|
|
287
|
+
* 1. Default: left-align the keypad with the left edge of the response area.
|
|
288
|
+
*
|
|
289
|
+
* 2. Overflow: if left-aligning would push the right edge of the keypad past
|
|
290
|
+
* the viewport's right edge, right-align the keypad so that its right edge
|
|
291
|
+
* sits exactly at the left edge of the response area.
|
|
292
|
+
*
|
|
293
|
+
* In both cases we compute offsets.x from first principles (rather than
|
|
294
|
+
* adjusting whatever Popper already set) to avoid any upstream skew.
|
|
295
|
+
*
|
|
296
|
+
* Coordinate note:
|
|
297
|
+
* state.rects.reference.x — reference's left edge in offset-parent coords.
|
|
298
|
+
* getBoundingClientRect() — viewport-relative coords.
|
|
299
|
+
* Both describe the same physical point, so the difference between them is
|
|
300
|
+
* the constant offset needed to convert viewport ↔ offset-parent coords.
|
|
301
|
+
*/
|
|
302
|
+
const smartHorizontalPlacementModifier = {
|
|
303
|
+
name: 'smartHorizontalPlacement',
|
|
304
|
+
enabled: true,
|
|
305
|
+
phase: 'main',
|
|
306
|
+
requires: ['popperOffsets'],
|
|
307
|
+
fn: ({
|
|
308
|
+
state
|
|
309
|
+
}) => {
|
|
310
|
+
const offsets = state.modifiersData.popperOffsets;
|
|
311
|
+
if (!offsets) return;
|
|
312
|
+
const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
313
|
+
const popperWidth = state.rects.popper.width;
|
|
314
|
+
const referenceViewportLeft = state.elements.reference.getBoundingClientRect().left;
|
|
315
|
+
const offsetParentEl = state.elements.popper?.offsetParent;
|
|
316
|
+
const offsetParentRect = offsetParentEl?.getBoundingClientRect?.() || {
|
|
317
|
+
left: 0
|
|
318
|
+
};
|
|
319
|
+
const offsetParentScrollLeft = offsetParentEl?.scrollLeft || 0;
|
|
320
|
+
const referenceOffsetParentX = referenceViewportLeft - offsetParentRect.left + offsetParentScrollLeft;
|
|
321
|
+
const viewportLeftInOffsetParent = referenceOffsetParentX - referenceViewportLeft;
|
|
322
|
+
const minX = viewportLeftInOffsetParent + KEYPAD_VIEWPORT_PADDING;
|
|
323
|
+
const maxX = viewportLeftInOffsetParent + viewportWidth - popperWidth - KEYPAD_VIEWPORT_PADDING;
|
|
324
|
+
if (referenceViewportLeft + popperWidth <= viewportWidth) {
|
|
325
|
+
offsets.x = referenceOffsetParentX;
|
|
326
|
+
} else {
|
|
327
|
+
offsets.x = referenceOffsetParentX - popperWidth;
|
|
328
|
+
}
|
|
329
|
+
if (maxX < minX) {
|
|
330
|
+
offsets.x = minX;
|
|
331
|
+
} else {
|
|
332
|
+
offsets.x = Math.min(Math.max(offsets.x, minX), maxX);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
class Main extends _react.default.Component {
|
|
337
|
+
constructor(props) {
|
|
338
|
+
super(props);
|
|
339
|
+
(0, _defineProperty2.default)(this, "handleAnswerBlockDomUpdate", () => {
|
|
340
|
+
const {
|
|
341
|
+
model
|
|
342
|
+
} = this.props;
|
|
343
|
+
const {
|
|
344
|
+
session,
|
|
345
|
+
showCorrect
|
|
346
|
+
} = this.state;
|
|
347
|
+
const answers = session.answers;
|
|
348
|
+
if (this.root && model.disabled && !showCorrect) {
|
|
349
|
+
Object.keys(answers).forEach(answerId => {
|
|
350
|
+
const el = this.root.querySelector(`#${answerId}`);
|
|
351
|
+
const indexEl = this.root.querySelector(`#${answerId}Index`);
|
|
352
|
+
if (el) {
|
|
353
|
+
const answer = answers[answerId];
|
|
354
|
+
(0, _mathInput.applyStaticMath)(el, answer && answer.value || '');
|
|
355
|
+
if (model.view) {
|
|
356
|
+
el.parentElement.parentElement.classList.remove('correct');
|
|
357
|
+
el.parentElement.parentElement.classList.remove('incorrect');
|
|
358
|
+
}
|
|
359
|
+
indexEl.textContent = 'R';
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
(0, _mathRendering.renderMath)(this.root);
|
|
364
|
+
});
|
|
365
|
+
(0, _defineProperty2.default)(this, "onSubFieldFocus", id => {
|
|
366
|
+
const editableFields = Array.from(this.root?.querySelectorAll('.mq-editable-field') || []);
|
|
367
|
+
const savedScroll = editableFields.map(el => ({
|
|
368
|
+
el,
|
|
369
|
+
left: el.scrollLeft,
|
|
370
|
+
top: el.scrollTop
|
|
371
|
+
}));
|
|
372
|
+
const restoreEditableScroll = () => {
|
|
373
|
+
savedScroll.forEach(({
|
|
374
|
+
el,
|
|
375
|
+
left,
|
|
376
|
+
top
|
|
377
|
+
}) => {
|
|
378
|
+
el.scrollLeft = left;
|
|
379
|
+
el.scrollTop = top;
|
|
380
|
+
});
|
|
381
|
+
};
|
|
382
|
+
this.setState({
|
|
383
|
+
activeAnswerBlock: id
|
|
384
|
+
}, () => {
|
|
385
|
+
restoreEditableScroll();
|
|
386
|
+
requestAnimationFrame(restoreEditableScroll);
|
|
387
|
+
setTimeout(restoreEditableScroll, 0);
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
(0, _defineProperty2.default)(this, "toNodeData", data => {
|
|
391
|
+
if (!data) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
const {
|
|
395
|
+
type,
|
|
396
|
+
value
|
|
397
|
+
} = data;
|
|
398
|
+
if (type === 'command' || type === 'cursor') return data;
|
|
399
|
+
if (type === 'answer') return {
|
|
400
|
+
type: 'answer',
|
|
401
|
+
...data
|
|
402
|
+
};
|
|
403
|
+
if (value === 'clear') return {
|
|
404
|
+
type: 'clear'
|
|
405
|
+
};
|
|
406
|
+
return {
|
|
407
|
+
type: 'write',
|
|
408
|
+
value
|
|
409
|
+
};
|
|
410
|
+
});
|
|
411
|
+
(0, _defineProperty2.default)(this, "setInput", input => {
|
|
412
|
+
this.input = input;
|
|
413
|
+
});
|
|
414
|
+
(0, _defineProperty2.default)(this, "onClick", data => {
|
|
415
|
+
const c = this.toNodeData(data);
|
|
416
|
+
if (c.type === 'clear') {
|
|
417
|
+
this.input.clear();
|
|
418
|
+
} else if (c.type === 'command') {
|
|
419
|
+
if (Array.isArray(c.value)) {
|
|
420
|
+
c.value.forEach(vv => {
|
|
421
|
+
this.input.cmd(vv);
|
|
422
|
+
});
|
|
423
|
+
} else {
|
|
424
|
+
this.input.cmd(c.value);
|
|
425
|
+
}
|
|
426
|
+
} else if (c.type === 'cursor') {
|
|
427
|
+
this.input.keystroke(c.value);
|
|
428
|
+
} else {
|
|
429
|
+
this.input.write(c.value);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Keep all relevant scroll containers stable when refocusing after keypad
|
|
433
|
+
// click. Browser "focus into view" can scroll horizontally back to start.
|
|
434
|
+
const fieldElement = this.input?.el?.() || this.root;
|
|
435
|
+
const scrollTargets = [];
|
|
436
|
+
let node = fieldElement;
|
|
437
|
+
while (node && node !== document.body && node !== document.documentElement) {
|
|
438
|
+
const isScrollable = node.scrollWidth > node.clientWidth || node.scrollHeight > node.clientHeight;
|
|
439
|
+
if (isScrollable) {
|
|
440
|
+
scrollTargets.push(node);
|
|
441
|
+
}
|
|
442
|
+
node = node.parentElement;
|
|
443
|
+
}
|
|
444
|
+
if (document.scrollingElement) {
|
|
445
|
+
scrollTargets.push(document.scrollingElement);
|
|
446
|
+
}
|
|
447
|
+
const savedScroll = scrollTargets.map(el => ({
|
|
448
|
+
el,
|
|
449
|
+
left: el.scrollLeft,
|
|
450
|
+
top: el.scrollTop
|
|
451
|
+
}));
|
|
452
|
+
const windowScroll = {
|
|
453
|
+
x: window.scrollX,
|
|
454
|
+
y: window.scrollY
|
|
455
|
+
};
|
|
456
|
+
const restoreScroll = () => {
|
|
457
|
+
savedScroll.forEach(({
|
|
458
|
+
el,
|
|
459
|
+
left,
|
|
460
|
+
top
|
|
461
|
+
}) => {
|
|
462
|
+
el.scrollLeft = left;
|
|
463
|
+
el.scrollTop = top;
|
|
464
|
+
});
|
|
465
|
+
window.scrollTo(windowScroll.x, windowScroll.y);
|
|
466
|
+
};
|
|
467
|
+
this.input.focus();
|
|
468
|
+
restoreScroll();
|
|
469
|
+
requestAnimationFrame(restoreScroll);
|
|
470
|
+
setTimeout(restoreScroll, 0);
|
|
471
|
+
});
|
|
472
|
+
(0, _defineProperty2.default)(this, "callOnSessionChange", () => {
|
|
473
|
+
const {
|
|
474
|
+
onSessionChange
|
|
475
|
+
} = this.props;
|
|
476
|
+
if (onSessionChange) {
|
|
477
|
+
onSessionChange(this.state.session);
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
(0, _defineProperty2.default)(this, "toggleShowCorrect", show => {
|
|
481
|
+
this.setState({
|
|
482
|
+
showCorrect: show
|
|
483
|
+
}, this.handleAnswerBlockDomUpdate);
|
|
484
|
+
});
|
|
485
|
+
(0, _defineProperty2.default)(this, "subFieldChanged", (name, subfieldValue) => {
|
|
486
|
+
(0, _mathInput.updateSpans)();
|
|
487
|
+
if (name) {
|
|
488
|
+
this.setState(state => ({
|
|
489
|
+
session: {
|
|
490
|
+
...state.session,
|
|
491
|
+
answers: {
|
|
492
|
+
...state.session.answers,
|
|
493
|
+
[name]: {
|
|
494
|
+
value: subfieldValue
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}), this.callOnSessionChange);
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
(0, _defineProperty2.default)(this, "getFieldName", (changeField, fields) => {
|
|
502
|
+
const {
|
|
503
|
+
answers
|
|
504
|
+
} = this.state.session;
|
|
505
|
+
if (Object.keys(answers || {}).length) {
|
|
506
|
+
const keys = Object.keys(answers);
|
|
507
|
+
return keys.find(k => {
|
|
508
|
+
const tf = fields[k];
|
|
509
|
+
return tf && tf.id == changeField.id;
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
(0, _defineProperty2.default)(this, "onBlur", e => {
|
|
514
|
+
const {
|
|
515
|
+
relatedTarget,
|
|
516
|
+
currentTarget
|
|
517
|
+
} = e || {};
|
|
518
|
+
function getParentWithRoleTooltip(element, depth = 0) {
|
|
519
|
+
// only run this max 16 times
|
|
520
|
+
if (!element || depth >= 16) return null;
|
|
521
|
+
const parent = element.offsetParent;
|
|
522
|
+
if (!parent) return null;
|
|
523
|
+
if (parent.getAttribute('role') === 'tooltip') {
|
|
524
|
+
return parent;
|
|
525
|
+
}
|
|
526
|
+
return getParentWithRoleTooltip(parent, depth + 1);
|
|
527
|
+
}
|
|
528
|
+
function getDeepChildDataKeypad(element, depth = 0) {
|
|
529
|
+
// only run this max 4 times
|
|
530
|
+
if (!element || depth >= 4) return null;
|
|
531
|
+
const child = element?.children?.[0];
|
|
532
|
+
if (!child) return null;
|
|
533
|
+
if (child.attributes && child.attributes['data-keypad']) {
|
|
534
|
+
return child;
|
|
535
|
+
}
|
|
536
|
+
return getDeepChildDataKeypad(child, depth + 1);
|
|
537
|
+
}
|
|
538
|
+
const parentWithTooltipRole = getParentWithRoleTooltip(relatedTarget);
|
|
539
|
+
const childWithDataKeypad = parentWithTooltipRole ? getDeepChildDataKeypad(parentWithTooltipRole) : null;
|
|
540
|
+
if (!relatedTarget || !currentTarget || !childWithDataKeypad?.attributes['data-keypad']) {
|
|
541
|
+
this.setState({
|
|
542
|
+
activeAnswerBlock: ''
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
(0, _defineProperty2.default)(this, "renderTeacherInstructions", () => {
|
|
547
|
+
const {
|
|
548
|
+
model
|
|
549
|
+
} = this.props;
|
|
550
|
+
const {
|
|
551
|
+
teacherInstructions,
|
|
552
|
+
animationsDisabled
|
|
553
|
+
} = model || {};
|
|
554
|
+
const showTeacherInstructions = teacherInstructions && ((0, _renderUi.hasText)(teacherInstructions) || (0, _renderUi.hasMedia)(teacherInstructions));
|
|
555
|
+
const teacherInstructionsDiv = /*#__PURE__*/_react.default.createElement(_renderUi.PreviewPrompt, {
|
|
556
|
+
defaultClassName: "teacher-instructions",
|
|
557
|
+
prompt: teacherInstructions
|
|
558
|
+
});
|
|
559
|
+
return showTeacherInstructions && /*#__PURE__*/_react.default.createElement(CollapsibleContainer, null, !animationsDisabled ? /*#__PURE__*/_react.default.createElement(_renderUi.Collapsible, {
|
|
560
|
+
labels: {
|
|
561
|
+
hidden: 'Show Teacher Instructions',
|
|
562
|
+
visible: 'Hide Teacher Instructions'
|
|
563
|
+
}
|
|
564
|
+
}, teacherInstructionsDiv) : teacherInstructionsDiv);
|
|
565
|
+
});
|
|
566
|
+
(0, _defineProperty2.default)(this, "renderRationale", () => {
|
|
567
|
+
const {
|
|
568
|
+
model
|
|
569
|
+
} = this.props;
|
|
570
|
+
const {
|
|
571
|
+
rationale,
|
|
572
|
+
animationsDisabled
|
|
573
|
+
} = model || {};
|
|
574
|
+
const rationaleDiv = /*#__PURE__*/_react.default.createElement(_renderUi.PreviewPrompt, {
|
|
575
|
+
prompt: rationale
|
|
576
|
+
});
|
|
577
|
+
const showRationale = rationale && ((0, _renderUi.hasText)(rationale) || (0, _renderUi.hasMedia)(rationale));
|
|
578
|
+
return showRationale && /*#__PURE__*/_react.default.createElement(CollapsibleContainer, null, !animationsDisabled ? /*#__PURE__*/_react.default.createElement(_renderUi.Collapsible, {
|
|
579
|
+
labels: {
|
|
580
|
+
hidden: 'Show Rationale',
|
|
581
|
+
visible: 'Hide Rationale'
|
|
582
|
+
}
|
|
583
|
+
}, rationaleDiv) : rationaleDiv);
|
|
584
|
+
});
|
|
585
|
+
(0, _defineProperty2.default)(this, "renderPlayerContent", () => {
|
|
586
|
+
const {
|
|
587
|
+
model
|
|
588
|
+
} = this.props;
|
|
589
|
+
const {
|
|
590
|
+
activeAnswerBlock,
|
|
591
|
+
showCorrect,
|
|
592
|
+
session,
|
|
593
|
+
tooltipContainerRef
|
|
594
|
+
} = this.state;
|
|
595
|
+
const {
|
|
596
|
+
correctness,
|
|
597
|
+
disabled,
|
|
598
|
+
view,
|
|
599
|
+
responses,
|
|
600
|
+
equationEditor,
|
|
601
|
+
customKeys,
|
|
602
|
+
feedback,
|
|
603
|
+
env: {
|
|
604
|
+
mode
|
|
605
|
+
} = {},
|
|
606
|
+
printMode,
|
|
607
|
+
alwaysShowCorrect
|
|
608
|
+
} = model || {};
|
|
609
|
+
const emptyResponse = (0, _lodashEs.isEmpty)(responses);
|
|
610
|
+
const additionalKeys = generateAdditionalKeys(customKeys);
|
|
611
|
+
const statics = prepareForStatic(model, this.state) || '';
|
|
612
|
+
const studentPrintMode = printMode && !alwaysShowCorrect;
|
|
613
|
+
return /*#__PURE__*/_react.default.createElement(InputAndKeypadContainer, null, /*#__PURE__*/_react.default.createElement(_maskMarkup.Customizable, {
|
|
614
|
+
disabled: disabled,
|
|
615
|
+
markup: model.markup
|
|
616
|
+
// TODO remove the need of value?
|
|
617
|
+
,
|
|
618
|
+
value: {},
|
|
619
|
+
customMarkMarkupComponent: id => {
|
|
620
|
+
const responseIsCorrect = mode === 'evaluate' && feedback && feedback[id];
|
|
621
|
+
const MQStatic = /*#__PURE__*/_react.default.createElement(StyledStatic, {
|
|
622
|
+
ref: mqStatic => {
|
|
623
|
+
this.mqStatic = mqStatic || this.mqStatic;
|
|
624
|
+
},
|
|
625
|
+
latex: statics[id],
|
|
626
|
+
onSubFieldChange: this.subFieldChanged,
|
|
627
|
+
getFieldName: this.getFieldName,
|
|
628
|
+
setInput: this.setInput,
|
|
629
|
+
onSubFieldFocus: this.onSubFieldFocus,
|
|
630
|
+
onBlur: this.onBlur
|
|
631
|
+
});
|
|
632
|
+
return /*#__PURE__*/_react.default.createElement(Expression, {
|
|
633
|
+
ref: tooltipContainerRef,
|
|
634
|
+
$incorrect: !emptyResponse && !responseIsCorrect && !showCorrect,
|
|
635
|
+
$correct: !emptyResponse && (responseIsCorrect || showCorrect),
|
|
636
|
+
$showCorrectness: !emptyResponse && disabled && correctness && !view,
|
|
637
|
+
$correctAnswerShown: showCorrect
|
|
638
|
+
}, /*#__PURE__*/_react.default.createElement(_Tooltip.default, {
|
|
639
|
+
ref: ref => this.setTooltipRef(ref),
|
|
640
|
+
enterTouchDelay: 0,
|
|
641
|
+
interactive: true,
|
|
642
|
+
open: activeAnswerBlock === `r${id}`,
|
|
643
|
+
slotProps: {
|
|
644
|
+
popper: {
|
|
645
|
+
container: tooltipContainerRef?.current || undefined,
|
|
646
|
+
// 'bottom-start' left-aligns the keypad with the left edge of the
|
|
647
|
+
// response area by default. The smartHorizontalPlacement modifier
|
|
648
|
+
// below overrides this when the keypad would overflow the viewport.
|
|
649
|
+
placement: 'bottom-start',
|
|
650
|
+
sx: {
|
|
651
|
+
backgroundColor: 'transparent',
|
|
652
|
+
width: 'auto',
|
|
653
|
+
opacity: 1,
|
|
654
|
+
'& .MuiTooltip-arrow': {
|
|
655
|
+
display: 'none'
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
modifiers: [{
|
|
659
|
+
name: 'preventOverflow',
|
|
660
|
+
enabled: false
|
|
661
|
+
}, {
|
|
662
|
+
name: 'flip',
|
|
663
|
+
enabled: false
|
|
664
|
+
}, smartHorizontalPlacementModifier]
|
|
665
|
+
},
|
|
666
|
+
tooltip: {
|
|
667
|
+
sx: {
|
|
668
|
+
fontSize: 'initial',
|
|
669
|
+
backgroundColor: 'transparent',
|
|
670
|
+
width: 'auto',
|
|
671
|
+
maxWidth: 'none',
|
|
672
|
+
marginTop: 0,
|
|
673
|
+
paddingTop: 0,
|
|
674
|
+
boxShadow: 'none'
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
},
|
|
678
|
+
title: Object.keys(session.answers).map(answerId => answerId === activeAnswerBlock && !(showCorrect || disabled) && /*#__PURE__*/_react.default.createElement(ResponseContainer, {
|
|
679
|
+
"data-keypad": true,
|
|
680
|
+
key: answerId,
|
|
681
|
+
style: {
|
|
682
|
+
width: getKeyPadWidth(additionalKeys, equationEditor)
|
|
683
|
+
}
|
|
684
|
+
}, /*#__PURE__*/_react.default.createElement(_mathInput.HorizontalKeypad, {
|
|
685
|
+
additionalKeys: additionalKeys,
|
|
686
|
+
mode: equationEditor || DEFAULT_KEYPAD_VARIANT,
|
|
687
|
+
onClick: this.onClick
|
|
688
|
+
})) || null)
|
|
689
|
+
}, studentPrintMode ? /*#__PURE__*/_react.default.createElement(PrintContainer, null, MQStatic) : /*#__PURE__*/_react.default.createElement("div", null, MQStatic)));
|
|
690
|
+
}
|
|
691
|
+
}));
|
|
692
|
+
});
|
|
693
|
+
const _answers = {};
|
|
694
|
+
const {
|
|
695
|
+
model: _model,
|
|
696
|
+
session: _session
|
|
697
|
+
} = props || {};
|
|
698
|
+
const {
|
|
699
|
+
markup,
|
|
700
|
+
alwaysShowCorrect: _alwaysShowCorrect
|
|
701
|
+
} = _model || {};
|
|
702
|
+
const {
|
|
703
|
+
answers: sessionAnswers
|
|
704
|
+
} = _session || {};
|
|
705
|
+
if (markup) {
|
|
706
|
+
(markup || '').replace(REGEX, response => {
|
|
707
|
+
const responseKey = Main.getResponseKey(response);
|
|
708
|
+
const sessionAnswerForResponse = sessionAnswers && sessionAnswers[`r${responseKey}`];
|
|
709
|
+
_answers[`r${responseKey}`] = {
|
|
710
|
+
value: sessionAnswerForResponse?.value || ''
|
|
711
|
+
};
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
this.state = {
|
|
715
|
+
session: {
|
|
716
|
+
...props.session,
|
|
717
|
+
answers: _answers
|
|
718
|
+
},
|
|
719
|
+
activeAnswerBlock: '',
|
|
720
|
+
showCorrect: _alwaysShowCorrect || false,
|
|
721
|
+
tooltipContainerRef: /*#__PURE__*/_react.default.createRef()
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
UNSAFE_componentWillMount() {
|
|
725
|
+
if (typeof window !== 'undefined') {
|
|
726
|
+
if (!registered) {
|
|
727
|
+
(0, _mathInput.registerEmbed)('answerBlock', data => ({
|
|
728
|
+
htmlString: `<div class="block-container">
|
|
729
|
+
<div class="block-response" id="${data}Index">R</div>
|
|
730
|
+
<div class="block-math">
|
|
731
|
+
<span id="${data}"></span>
|
|
732
|
+
</div>
|
|
733
|
+
</div>`,
|
|
734
|
+
text: () => 'text',
|
|
735
|
+
latex: () => `\\embed{answerBlock}[${data}]`
|
|
736
|
+
}));
|
|
737
|
+
registered = true;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
742
|
+
const {
|
|
743
|
+
model
|
|
744
|
+
} = this.props;
|
|
745
|
+
const {
|
|
746
|
+
model: nextModel = {}
|
|
747
|
+
} = nextProps || {};
|
|
748
|
+
const {
|
|
749
|
+
markup = '',
|
|
750
|
+
env = {}
|
|
751
|
+
} = model || {};
|
|
752
|
+
const {
|
|
753
|
+
markup: nextMarkup = '',
|
|
754
|
+
env: nextEnv = {},
|
|
755
|
+
alwaysShowCorrect: nextAlwaysShowCorrect = false
|
|
756
|
+
} = nextModel;
|
|
757
|
+
const isEvaluateMode = env => env && env.mode === 'evaluate';
|
|
758
|
+
if (!isEvaluateMode(env) || !isEvaluateMode(nextEnv)) {
|
|
759
|
+
this.setState(prevState => ({
|
|
760
|
+
...prevState.session,
|
|
761
|
+
showCorrect: false
|
|
762
|
+
}));
|
|
763
|
+
}
|
|
764
|
+
if (nextAlwaysShowCorrect) {
|
|
765
|
+
this.setState({
|
|
766
|
+
showCorrect: true
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
const matches = markup.match(REGEX);
|
|
770
|
+
const nextMatches = nextMarkup.match(REGEX);
|
|
771
|
+
|
|
772
|
+
// If markup changed, and we no longer have the same response area, the session needs to be updated
|
|
773
|
+
if (!(0, _lodashEs.isEqual)(matches, nextMatches)) {
|
|
774
|
+
const newAnswers = {};
|
|
775
|
+
const answers = this.state.session.answers;
|
|
776
|
+
(nextMatches || []).forEach(nextMatch => {
|
|
777
|
+
const responseKey = Main.getResponseKey(nextMatch);
|
|
778
|
+
const sessionAnswerForResponse = answers && answers[`r${responseKey}`];
|
|
779
|
+
|
|
780
|
+
// build out local state model using responses declared in markup
|
|
781
|
+
newAnswers[`r${responseKey}`] = {
|
|
782
|
+
value: sessionAnswerForResponse?.value || ''
|
|
783
|
+
};
|
|
784
|
+
});
|
|
785
|
+
this.setState(state => ({
|
|
786
|
+
session: {
|
|
787
|
+
...state.session,
|
|
788
|
+
answers: newAnswers
|
|
789
|
+
}
|
|
790
|
+
}), () => {
|
|
791
|
+
this.props.onSessionChange(this.state.session);
|
|
792
|
+
this.handleAnswerBlockDomUpdate();
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
shouldComponentUpdate(nextProps, nextState) {
|
|
797
|
+
const sameModel = (0, _lodashEs.isEqual)(this.props.model, nextProps.model);
|
|
798
|
+
const sameState = (0, _lodashEs.isEqual)(this.state, nextState);
|
|
799
|
+
return !sameModel || !sameState;
|
|
800
|
+
}
|
|
801
|
+
componentDidMount() {
|
|
802
|
+
this.handleAnswerBlockDomUpdate();
|
|
803
|
+
setTimeout(() => (0, _mathRendering.renderMath)(this.root), 100);
|
|
804
|
+
}
|
|
805
|
+
componentDidUpdate() {
|
|
806
|
+
this.handleAnswerBlockDomUpdate();
|
|
807
|
+
}
|
|
808
|
+
// function for tooltip
|
|
809
|
+
setTooltipRef(ref) {
|
|
810
|
+
// Safari Hack: https://stackoverflow.com/a/42764495/5757635
|
|
811
|
+
setTimeout(() => {
|
|
812
|
+
if (ref && IS_SAFARI) {
|
|
813
|
+
const div = document.querySelector("[role='tooltip']");
|
|
814
|
+
if (div) {
|
|
815
|
+
const el = div.firstChild;
|
|
816
|
+
el.setAttribute('tabindex', '-1');
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}, 1);
|
|
820
|
+
}
|
|
821
|
+
render() {
|
|
822
|
+
const {
|
|
823
|
+
model
|
|
824
|
+
} = this.props;
|
|
825
|
+
const {
|
|
826
|
+
showCorrect
|
|
827
|
+
} = this.state;
|
|
828
|
+
const {
|
|
829
|
+
prompt,
|
|
830
|
+
env: {
|
|
831
|
+
mode,
|
|
832
|
+
role
|
|
833
|
+
} = {},
|
|
834
|
+
extraCSSRules,
|
|
835
|
+
correctness,
|
|
836
|
+
responses,
|
|
837
|
+
language,
|
|
838
|
+
showNote,
|
|
839
|
+
note
|
|
840
|
+
} = model || {};
|
|
841
|
+
const emptyResponse = (0, _lodashEs.isEmpty)(responses);
|
|
842
|
+
const showCorrectAnswerToggle = !emptyResponse && correctness && correctness.correctness !== 'correct';
|
|
843
|
+
const displayNote = (showCorrect || mode === 'view' && role === 'instructor') && showNote && note;
|
|
844
|
+
return /*#__PURE__*/_react.default.createElement(StyledUiLayout, {
|
|
845
|
+
extraCSSRules: extraCSSRules,
|
|
846
|
+
ref: r => {
|
|
847
|
+
// eslint-disable-next-line react/no-find-dom-node
|
|
848
|
+
const domNode = _reactDom.default.findDOMNode(r);
|
|
849
|
+
this.root = domNode || this.root;
|
|
850
|
+
}
|
|
851
|
+
}, /*#__PURE__*/_react.default.createElement(MainContainer, null, mode === 'gather' && /*#__PURE__*/_react.default.createElement(SrOnly, null, "Math Equation Response Question"), /*#__PURE__*/_react.default.createElement(MainContainer, null, showCorrectAnswerToggle && /*#__PURE__*/_react.default.createElement(StyledToggle, {
|
|
852
|
+
language: language,
|
|
853
|
+
show: true,
|
|
854
|
+
toggled: showCorrect,
|
|
855
|
+
onToggle: this.toggleShowCorrect
|
|
856
|
+
})), this.renderTeacherInstructions(), prompt && /*#__PURE__*/_react.default.createElement(PromptContainer, null, /*#__PURE__*/_react.default.createElement(_renderUi.PreviewPrompt, {
|
|
857
|
+
prompt: prompt
|
|
858
|
+
})), /*#__PURE__*/_react.default.createElement(_renderUi.Readable, {
|
|
859
|
+
false: true
|
|
860
|
+
}, this.renderPlayerContent()), displayNote && /*#__PURE__*/_react.default.createElement(Note, {
|
|
861
|
+
className: "note",
|
|
862
|
+
dangerouslySetInnerHTML: {
|
|
863
|
+
__html: note
|
|
864
|
+
}
|
|
865
|
+
}), this.renderRationale()));
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
exports.Main = Main;
|
|
869
|
+
// removes {{ and }} and returns only key response. Eg: {{0}} => 0
|
|
870
|
+
(0, _defineProperty2.default)(Main, "getResponseKey", response => (response || '').replaceAll('{{', '').replaceAll('}}', ''));
|
|
871
|
+
(0, _defineProperty2.default)(Main, "propTypes", {
|
|
872
|
+
session: _propTypes.default.object.isRequired,
|
|
873
|
+
onSessionChange: _propTypes.default.func,
|
|
874
|
+
model: _propTypes.default.object.isRequired
|
|
875
|
+
});
|
|
876
|
+
var _default = exports.default = Main;
|
|
877
|
+
//# sourceMappingURL=main.js.map
|