@citolab/qti-components 8.2.0 → 9.1.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.
- package/cdn/index.global.js +1 -1
- package/cdn/index.js +190 -190
- package/dist/base.js +1 -1
- package/dist/{chunk-OVBG223G.js → chunk-3VQSUWCK.js} +173 -12
- package/dist/chunk-3VQSUWCK.js.map +1 -0
- package/dist/{chunk-Q6ZK4LRH.js → chunk-5BXJRO5O.js} +1792 -551
- package/dist/chunk-5BXJRO5O.js.map +1 -0
- package/dist/{chunk-OIUK5BFU.js → chunk-5SU3MP6Y.js} +811 -811
- package/dist/chunk-5SU3MP6Y.js.map +1 -0
- package/dist/{chunk-LMGJOBJA.js → chunk-DAUU2NJL.js} +5 -5
- package/dist/chunk-DAUU2NJL.js.map +1 -0
- package/dist/chunk-KCK27QBP.js +11 -0
- package/dist/chunk-KCK27QBP.js.map +1 -0
- package/dist/{chunk-M7K5C522.js → chunk-LDY4C2OT.js} +2 -2
- package/dist/chunk-MKZ374OJ.js +179 -0
- package/dist/chunk-MKZ374OJ.js.map +1 -0
- package/dist/{chunk-CRLXQZFA.js → chunk-QCPN7E6K.js} +14 -10
- package/dist/chunk-QCPN7E6K.js.map +1 -0
- package/dist/{chunk-U7YCXDYC.js → chunk-RT6WZ3P7.js} +2 -2
- package/dist/{chunk-7D3NKAGZ.js → chunk-WCWJPIUQ.js} +5 -4
- package/dist/chunk-WCWJPIUQ.js.map +1 -0
- package/dist/{chunk-YLRMOX6C.js → chunk-WKWCOV5P.js} +2 -2
- package/dist/chunk-XE7BALDO.js +7 -0
- package/dist/chunk-XE7BALDO.js.map +1 -0
- package/dist/{chunk-UC3T3NI3.js → chunk-XYQNTF5B.js} +2 -2
- package/dist/corrections.js +82 -7
- package/dist/corrections.js.map +1 -1
- package/dist/elements.js +3 -3
- package/dist/index.js +24 -24
- package/dist/interactions.js +14 -15
- package/dist/item.js +4 -4
- package/dist/processing.d.ts +26 -0
- package/dist/processing.js +3 -2
- package/dist/qti-components-jsx.d.ts +60 -4
- package/dist/test.js +5 -5
- package/package.json +7 -7
- package/dist/chunk-43XBJ47H.js +0 -1420
- package/dist/chunk-43XBJ47H.js.map +0 -1
- package/dist/chunk-7D3NKAGZ.js.map +0 -1
- package/dist/chunk-CRLXQZFA.js.map +0 -1
- package/dist/chunk-LMGJOBJA.js.map +0 -1
- package/dist/chunk-OIUK5BFU.js.map +0 -1
- package/dist/chunk-OVBG223G.js.map +0 -1
- package/dist/chunk-Q6ZK4LRH.js.map +0 -1
- package/dist/chunk-TLTYXWW7.js +0 -7
- package/dist/chunk-TLTYXWW7.js.map +0 -1
- /package/dist/{chunk-M7K5C522.js.map → chunk-LDY4C2OT.js.map} +0 -0
- /package/dist/{chunk-U7YCXDYC.js.map → chunk-RT6WZ3P7.js.map} +0 -0
- /package/dist/{chunk-YLRMOX6C.js.map → chunk-WKWCOV5P.js.map} +0 -0
- /package/dist/{chunk-UC3T3NI3.js.map → chunk-XYQNTF5B.js.map} +0 -0
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
QtiTest,
|
|
3
3
|
TestCheckItem,
|
|
4
4
|
TestNavigation
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QCPN7E6K.js";
|
|
6
6
|
import {
|
|
7
7
|
QtiAssessmentItem
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WKWCOV5P.js";
|
|
9
9
|
import {
|
|
10
10
|
QtiAssociateInteraction,
|
|
11
11
|
QtiChoiceInteraction,
|
|
@@ -28,10 +28,10 @@ import {
|
|
|
28
28
|
QtiSimpleChoice,
|
|
29
29
|
QtiSliderInteraction,
|
|
30
30
|
QtiTextEntryInteraction
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-5BXJRO5O.js";
|
|
32
32
|
import {
|
|
33
33
|
QtiItem
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-DAUU2NJL.js";
|
|
35
35
|
import {
|
|
36
36
|
watch
|
|
37
37
|
} from "./chunk-4DB4SC5K.js";
|
|
@@ -41,907 +41,758 @@ import {
|
|
|
41
41
|
computedItemContext,
|
|
42
42
|
configContext,
|
|
43
43
|
responseAttributeConverter
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-WCWJPIUQ.js";
|
|
45
45
|
|
|
46
|
-
// ../qti-corrections/dist/
|
|
46
|
+
// ../qti-corrections/dist/components/item-correct-response-mode/item-correct-response-mode.js
|
|
47
|
+
import { html, LitElement } from "lit";
|
|
47
48
|
import { property, state } from "lit/decorators.js";
|
|
49
|
+
import { consume } from "@lit/context";
|
|
48
50
|
var __decorate = function(decorators, target, key, desc) {
|
|
49
51
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
50
52
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
51
53
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
52
54
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
53
55
|
};
|
|
54
|
-
var
|
|
55
|
-
(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
constructor() {
|
|
63
|
-
super(...arguments);
|
|
64
|
-
this.showCorrectResponse = false;
|
|
65
|
-
this._handleShowCorrectResponseChange = (_, show) => {
|
|
66
|
-
this.toggleInternalCorrectResponse(show);
|
|
67
|
-
};
|
|
68
|
-
this.showFullCorrectResponse = false;
|
|
69
|
-
this._handleShowFullCorrectResponseChange = (_, show) => {
|
|
70
|
-
this.toggleFullCorrectResponse(show);
|
|
71
|
-
};
|
|
72
|
-
this.showCandidateCorrection = false;
|
|
73
|
-
this._handleShowCandidateCorrectionChange = (_, show) => {
|
|
74
|
-
this.toggleCandidateCorrection(show);
|
|
75
|
-
};
|
|
76
|
-
this._correctResponse = null;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* The correct response for this interaction. Can be set as a comma-separated
|
|
80
|
-
* string via attribute or as string/string[] via property.
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```html
|
|
84
|
-
* <qti-choice-interaction correct-response="A,B">
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
set correctResponseAttr(val) {
|
|
88
|
-
this._correctResponse = val;
|
|
89
|
-
}
|
|
90
|
-
get correctResponseAttr() {
|
|
91
|
-
return this._correctResponse;
|
|
92
|
-
}
|
|
93
|
-
get isFullCorrectResponse() {
|
|
94
|
-
return this._isFullCorrectResponse;
|
|
95
|
-
}
|
|
96
|
-
get registersWithItem() {
|
|
97
|
-
return !this.isFullCorrectResponse && super.registersWithItem;
|
|
98
|
-
}
|
|
99
|
-
set isFullCorrectResponse(val) {
|
|
100
|
-
this._isFullCorrectResponse = val;
|
|
101
|
-
if (val) {
|
|
102
|
-
this.setAttribute("inert", "");
|
|
103
|
-
this.setAttribute("response-identifier", this.responseIdentifier + "_cr");
|
|
104
|
-
this.setAttribute("answer-key", "");
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
get correctResponse() {
|
|
108
|
-
const responseVariable = this.responseVariable;
|
|
109
|
-
if (responseVariable?.correctResponse) {
|
|
110
|
-
return responseVariable.correctResponse;
|
|
111
|
-
}
|
|
112
|
-
return this._correctResponse;
|
|
113
|
-
}
|
|
114
|
-
set correctResponse(val) {
|
|
115
|
-
const oldVal = this._correctResponse;
|
|
116
|
-
this._correctResponse = val;
|
|
117
|
-
if (val === null || val === void 0) {
|
|
118
|
-
this.removeAttribute("correct-response");
|
|
119
|
-
} else {
|
|
120
|
-
this.setAttribute("correct-response", Array.isArray(val) ? val.join(",") : val);
|
|
121
|
-
}
|
|
122
|
-
this.requestUpdate("_correctResponse", oldVal);
|
|
123
|
-
}
|
|
124
|
-
// ─── correctness getter ───────────────────────────────────────────────────
|
|
125
|
-
get correctness() {
|
|
126
|
-
const correctResponse = this.correctResponse;
|
|
127
|
-
if (!correctResponse)
|
|
128
|
-
return null;
|
|
129
|
-
const currentResponse = this.response;
|
|
130
|
-
if (currentResponse === null || currentResponse === void 0 || currentResponse === "" || Array.isArray(currentResponse) && currentResponse.length === 0) {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
const correctArr = Array.isArray(correctResponse) ? correctResponse : [correctResponse];
|
|
134
|
-
const responseArr = Array.isArray(currentResponse) ? currentResponse : [currentResponse];
|
|
135
|
-
const filteredResponseArr = responseArr.filter((r) => r !== "");
|
|
136
|
-
if (filteredResponseArr.length === 0)
|
|
137
|
-
return null;
|
|
138
|
-
const correctCount = filteredResponseArr.filter((r) => correctArr.includes(r)).length;
|
|
139
|
-
const incorrectCount = filteredResponseArr.filter((r) => !correctArr.includes(r)).length;
|
|
140
|
-
if (correctCount === correctArr.length && incorrectCount === 0 && filteredResponseArr.length === correctArr.length) {
|
|
141
|
-
return Correctness.Correct;
|
|
142
|
-
}
|
|
143
|
-
if (correctCount > 0 && (correctCount < correctArr.length || incorrectCount > 0)) {
|
|
144
|
-
return Correctness.PartiallyCorrect;
|
|
145
|
-
}
|
|
146
|
-
return Correctness.Incorrect;
|
|
147
|
-
}
|
|
148
|
-
// ─── correctionPart ───────────────────────────────────────────────────────
|
|
149
|
-
get correctionPart() {
|
|
150
|
-
return "correction";
|
|
151
|
-
}
|
|
152
|
-
// ─── toggle methods ───────────────────────────────────────────────────────
|
|
153
|
-
toggleCorrectResponse(show) {
|
|
154
|
-
const correctionConfig = this.configContext;
|
|
155
|
-
const correctResponseMode = correctionConfig?.correctResponseMode || "internal";
|
|
156
|
-
if (correctResponseMode === "full") {
|
|
157
|
-
this.toggleFullCorrectResponse(show);
|
|
158
|
-
} else {
|
|
159
|
-
this.toggleInternalCorrectResponse(show);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Whether the full correct response is withheld from a candidate who is already correct.
|
|
164
|
-
*
|
|
165
|
-
* Withheld by default, unless the item configures `fullCorrectResponseOnlyWhenIncorrect: false`
|
|
166
|
-
* — the behaviour `show-full-correct-response` has always had, on the reasoning that a correct
|
|
167
|
-
* answer already *is* the key.
|
|
168
|
-
*
|
|
169
|
-
* An interaction that routes its internal mode here overrides this to false: there, the caller
|
|
170
|
-
* asked to show the correct response, and silently showing nothing is worse than showing the
|
|
171
|
-
* candidate the answer they already gave.
|
|
172
|
-
*/
|
|
173
|
-
get withholdsFullCorrectResponseWhenCorrect() {
|
|
174
|
-
return this.configContext?.fullCorrectResponseOnlyWhenIncorrect !== false;
|
|
175
|
-
}
|
|
176
|
-
async toggleFullCorrectResponse(show) {
|
|
177
|
-
const nextSibling = this.nextSibling;
|
|
178
|
-
const nextSiblingIsFullCorrectResponse = nextSibling instanceof HTMLDivElement && nextSibling?.classList.contains("full-correct-response");
|
|
179
|
-
const correctResponse = this.correctResponse;
|
|
180
|
-
if (!correctResponse) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
const showFullCorrectResponse = show && (!this.withholdsFullCorrectResponseWhenCorrect || this.correctness !== Correctness.Correct);
|
|
184
|
-
if (!showFullCorrectResponse) {
|
|
185
|
-
if (!nextSiblingIsFullCorrectResponse) {
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
this.parentElement?.removeChild(nextSibling);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
if (nextSiblingIsFullCorrectResponse) {
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
const clone = this.cloneNode(true);
|
|
195
|
-
clone.removeAttribute("show-full-correct-response");
|
|
196
|
-
clone.removeAttribute("show-correct-response");
|
|
197
|
-
clone.removeAttribute("show-candidate-correction");
|
|
198
|
-
const containerDiv = document.createElement("div");
|
|
199
|
-
containerDiv.classList.add("full-correct-response");
|
|
200
|
-
if (this.isInline) {
|
|
201
|
-
containerDiv.classList.add("full-correct-response-inline");
|
|
202
|
-
} else {
|
|
203
|
-
containerDiv.classList.add("full-correct-response-block");
|
|
204
|
-
}
|
|
205
|
-
containerDiv.role = "full-correct-response";
|
|
206
|
-
containerDiv.appendChild(clone);
|
|
207
|
-
clone.isFullCorrectResponse = true;
|
|
208
|
-
this.parentElement?.insertBefore(containerDiv, this.nextSibling);
|
|
209
|
-
await clone.updateComplete;
|
|
210
|
-
clone.response = Array.isArray(correctResponse) ? [...correctResponse] : correctResponse;
|
|
211
|
-
}
|
|
212
|
-
toggleInternalCorrectResponse(show) {
|
|
213
|
-
this._internals.states.delete("show-correct-response");
|
|
214
|
-
if (show && this.correctResponse) {
|
|
215
|
-
this._internals.states.add("show-correct-response");
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
toggleCandidateCorrection(show) {
|
|
219
|
-
if (!show) {
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
// ─── Lifecycle ────────────────────────────────────────────────────────────
|
|
224
|
-
firstUpdated() {
|
|
225
|
-
super.firstUpdated();
|
|
226
|
-
if (this.isFullCorrectResponse) {
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
if (this.showCorrectResponse) {
|
|
230
|
-
this.toggleInternalCorrectResponse(true);
|
|
231
|
-
}
|
|
232
|
-
if (this.showFullCorrectResponse) {
|
|
233
|
-
this.toggleFullCorrectResponse(true);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
56
|
+
var ItemCorrectResponseMode = class extends LitElement {
|
|
57
|
+
constructor() {
|
|
58
|
+
super(...arguments);
|
|
59
|
+
this.label = "Correct response mode";
|
|
60
|
+
this._options = {
|
|
61
|
+
internal: "Internal",
|
|
62
|
+
full: "Full (copy)"
|
|
63
|
+
};
|
|
236
64
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
})
|
|
243
|
-
], CorrectResponseMixinClass.prototype, "correctResponseAttr", null);
|
|
244
|
-
__decorate([
|
|
245
|
-
property({ type: Boolean, attribute: "show-correct-response", reflect: true })
|
|
246
|
-
], CorrectResponseMixinClass.prototype, "showCorrectResponse", void 0);
|
|
247
|
-
__decorate([
|
|
248
|
-
watch("showCorrectResponse", { waitUntilFirstUpdate: true })
|
|
249
|
-
], CorrectResponseMixinClass.prototype, "_handleShowCorrectResponseChange", void 0);
|
|
250
|
-
__decorate([
|
|
251
|
-
property({ type: Boolean, attribute: "show-full-correct-response", reflect: true })
|
|
252
|
-
], CorrectResponseMixinClass.prototype, "showFullCorrectResponse", void 0);
|
|
253
|
-
__decorate([
|
|
254
|
-
watch("showFullCorrectResponse", { waitUntilFirstUpdate: true })
|
|
255
|
-
], CorrectResponseMixinClass.prototype, "_handleShowFullCorrectResponseChange", void 0);
|
|
256
|
-
__decorate([
|
|
257
|
-
property({ type: Boolean, attribute: "show-candidate-correction", reflect: true })
|
|
258
|
-
], CorrectResponseMixinClass.prototype, "showCandidateCorrection", void 0);
|
|
259
|
-
__decorate([
|
|
260
|
-
watch("showCandidateCorrection", { waitUntilFirstUpdate: true })
|
|
261
|
-
], CorrectResponseMixinClass.prototype, "_handleShowCandidateCorrectionChange", void 0);
|
|
262
|
-
__decorate([
|
|
263
|
-
state()
|
|
264
|
-
], CorrectResponseMixinClass.prototype, "_isFullCorrectResponse", void 0);
|
|
265
|
-
__decorate([
|
|
266
|
-
state()
|
|
267
|
-
], CorrectResponseMixinClass.prototype, "_correctResponse", void 0);
|
|
268
|
-
return CorrectResponseMixinClass;
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
// ../qti-corrections/dist/styles/correction.styles.js
|
|
272
|
-
import { css } from "lit";
|
|
273
|
-
var correctionPart = css`
|
|
274
|
-
/* Nothing at all until the item judges this element. */
|
|
275
|
-
[part~='correction'] {
|
|
276
|
-
display: none;
|
|
65
|
+
#switchMode(view) {
|
|
66
|
+
this.dispatchEvent(new CustomEvent("item-switch-correct-response-mode", {
|
|
67
|
+
detail: view,
|
|
68
|
+
bubbles: true
|
|
69
|
+
}));
|
|
277
70
|
}
|
|
71
|
+
render() {
|
|
72
|
+
return html`
|
|
73
|
+
<label part="label" for="modeSelect">${this.label}</label>
|
|
74
|
+
<select
|
|
75
|
+
part="select"
|
|
76
|
+
id="modeSelect"
|
|
77
|
+
@change=${(e) => {
|
|
78
|
+
const el = e.target;
|
|
79
|
+
this.#switchMode(el.value);
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
${Object.keys(this._options).map((value) => html`<option value="${value}" ?selected=${value === this.itemContext?.correctResponseMode}>
|
|
83
|
+
${this._options[value]}
|
|
84
|
+
</option>`)}
|
|
85
|
+
</select>
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
__decorate([
|
|
90
|
+
consume({ context: configContext, subscribe: true })
|
|
91
|
+
], ItemCorrectResponseMode.prototype, "itemContext", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
property({ type: String })
|
|
94
|
+
], ItemCorrectResponseMode.prototype, "label", void 0);
|
|
95
|
+
__decorate([
|
|
96
|
+
state()
|
|
97
|
+
], ItemCorrectResponseMode.prototype, "_options", void 0);
|
|
278
98
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
flex: 0 0 auto;
|
|
284
|
-
|
|
285
|
-
/*
|
|
286
|
-
* The badge aligns ITSELF, and that is the whole of the vertical story.
|
|
287
|
-
*
|
|
288
|
-
* It is a flex item with a definite height, so left alone its cross-axis position is decided by
|
|
289
|
-
* whatever its host says — and the hosts disagree: qti-simple-associable-choice defaults to
|
|
290
|
-
* align-items: normal, and qti-gap-text gates center behind :not([part~='drag']), so the
|
|
291
|
-
* same chip centred its badge in the bank and top-aligned it once placed. align-self settles it
|
|
292
|
-
* from the badge's side, in one line, without touching a single container.
|
|
293
|
-
*
|
|
294
|
-
* This replaces an align-items/justify-content: center pair that had never done anything: the
|
|
295
|
-
* badge is empty — a mask painted over a background — so centring its CONTENTS centres nothing.
|
|
296
|
-
*/
|
|
297
|
-
align-self: center;
|
|
298
|
-
|
|
299
|
-
box-sizing: border-box;
|
|
300
|
-
width: var(--qti-correction-size, 1em);
|
|
301
|
-
height: var(--qti-correction-size, 1em);
|
|
302
|
-
margin-left: var(--qti-glyph-gap, 0.5em);
|
|
99
|
+
// ../qti-corrections/dist/components/item-show-candidate-correction/item-show-candidate-correction.js
|
|
100
|
+
import { css as css2, html as html2, LitElement as LitElement2 } from "lit";
|
|
101
|
+
import { property as property2 } from "lit/decorators.js";
|
|
102
|
+
import { consume as consume2 } from "@lit/context";
|
|
303
103
|
|
|
304
|
-
|
|
305
|
-
|
|
104
|
+
// ../qti-corrections/dist/components/styles.js
|
|
105
|
+
import { css } from "lit";
|
|
106
|
+
var form = css`
|
|
107
|
+
display: inline-flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
cursor: pointer;
|
|
110
|
+
padding: 0.5rem 1rem;
|
|
111
|
+
border-radius: 0.25rem;
|
|
112
|
+
user-select: none;
|
|
113
|
+
`;
|
|
114
|
+
var btn = css`
|
|
115
|
+
background-color: lightgray;
|
|
116
|
+
${form};
|
|
117
|
+
`;
|
|
118
|
+
var dis = css`
|
|
119
|
+
cursor: not-allowed;
|
|
120
|
+
opacity: 0.8;
|
|
121
|
+
`;
|
|
122
|
+
var ind = css`
|
|
123
|
+
${form};
|
|
124
|
+
border: 1px solid gray;
|
|
306
125
|
`;
|
|
307
126
|
|
|
308
|
-
// ../qti-corrections/dist/
|
|
309
|
-
import { state as state2 } from "lit/decorators.js";
|
|
127
|
+
// ../qti-corrections/dist/components/item-show-candidate-correction/item-show-candidate-correction.js
|
|
310
128
|
var __decorate2 = function(decorators, target, key, desc) {
|
|
311
129
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
312
130
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
313
131
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
314
132
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
315
133
|
};
|
|
316
|
-
var
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
get correctionPart() {
|
|
323
|
-
return this._candidateCorrection ? `correction correction-${this._candidateCorrection}` : "correction";
|
|
324
|
-
}
|
|
325
|
-
toggleCandidateCorrection(show) {
|
|
326
|
-
if (this.showCandidateCorrection !== show) {
|
|
327
|
-
this.showCandidateCorrection = show;
|
|
328
|
-
}
|
|
329
|
-
super.toggleCandidateCorrection(show);
|
|
330
|
-
const internals = this._internals;
|
|
331
|
-
internals.states.delete("candidate-correct");
|
|
332
|
-
internals.states.delete("candidate-partially-correct");
|
|
333
|
-
internals.states.delete("candidate-incorrect");
|
|
334
|
-
let verdict = null;
|
|
335
|
-
if (show) {
|
|
336
|
-
if (this.correctness === Correctness.Correct) {
|
|
337
|
-
internals.states.add("candidate-correct");
|
|
338
|
-
verdict = "correct";
|
|
339
|
-
}
|
|
340
|
-
if (this.correctness === Correctness.PartiallyCorrect) {
|
|
341
|
-
internals.states.add("candidate-partially-correct");
|
|
342
|
-
verdict = "partially-correct";
|
|
343
|
-
}
|
|
344
|
-
if (this.correctness === Correctness.Incorrect) {
|
|
345
|
-
internals.states.add("candidate-incorrect");
|
|
346
|
-
verdict = "incorrect";
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
if (this._candidateCorrection !== verdict) {
|
|
350
|
-
this._candidateCorrection = verdict;
|
|
351
|
-
}
|
|
134
|
+
var ItemShowCandidateCorrection = class extends LitElement2 {
|
|
135
|
+
static {
|
|
136
|
+
this.styles = css2`
|
|
137
|
+
:host {
|
|
138
|
+
${btn};
|
|
352
139
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
queueMicrotask(() => {
|
|
356
|
-
if (!this.isConnected || this.isFullCorrectResponse) {
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
if (this.showCandidateCorrection) {
|
|
360
|
-
this.toggleCandidateCorrection(true);
|
|
361
|
-
}
|
|
362
|
-
});
|
|
140
|
+
:host([disabled]) {
|
|
141
|
+
${dis};
|
|
363
142
|
}
|
|
143
|
+
`;
|
|
364
144
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
for (const choice of this._choiceElements) {
|
|
379
|
-
choice.internals.states.delete("correct-response");
|
|
380
|
-
choice.internals.states.delete("incorrect-response");
|
|
381
|
-
if (show && correctResponses.length > 0) {
|
|
382
|
-
choice.internals.states.add(correctResponses.includes(choice.identifier) ? "correct-response" : "incorrect-response");
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
toggleCandidateCorrection(show) {
|
|
387
|
-
super.toggleCandidateCorrection(show);
|
|
388
|
-
for (const choice of this._choiceElements) {
|
|
389
|
-
choice.candidateCorrection = null;
|
|
390
|
-
}
|
|
391
|
-
if (!show || !this.correctResponse) {
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
const correctResponses = Array.isArray(this.correctResponse) ? this.correctResponse : [this.correctResponse];
|
|
395
|
-
const candidateResponses = Array.isArray(this.response) ? this.response : this.response ? [this.response] : [];
|
|
396
|
-
for (const choice of this._choiceElements) {
|
|
397
|
-
if (!candidateResponses.includes(choice.identifier)) {
|
|
398
|
-
continue;
|
|
399
|
-
}
|
|
400
|
-
choice.candidateCorrection = correctResponses.includes(choice.identifier) ? "correct" : "incorrect";
|
|
401
|
-
}
|
|
402
|
-
}
|
|
145
|
+
#hasCorrectResponse;
|
|
146
|
+
// correct response is removed on certain point
|
|
147
|
+
#previousActiveItem;
|
|
148
|
+
// Store previous active item reference
|
|
149
|
+
constructor() {
|
|
150
|
+
super();
|
|
151
|
+
this.shown = false;
|
|
152
|
+
this.disabled = false;
|
|
153
|
+
this.showCandidateCorrectionText = "Show candidate correction";
|
|
154
|
+
this.hideCandidateCorrectionText = "Hide candidate correction";
|
|
155
|
+
this.noCorrectResponseText = "No correct response specified";
|
|
156
|
+
this.#hasCorrectResponse = false;
|
|
157
|
+
this.#previousActiveItem = "";
|
|
403
158
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
class ActiveElementCorrectionMixinClass extends superClass {
|
|
413
|
-
#candidateCorrection = null;
|
|
414
|
-
get candidateCorrection() {
|
|
415
|
-
return this.#candidateCorrection;
|
|
416
|
-
}
|
|
417
|
-
set candidateCorrection(value) {
|
|
418
|
-
if (this.#candidateCorrection === value)
|
|
419
|
-
return;
|
|
420
|
-
const previous = this.#candidateCorrection;
|
|
421
|
-
this.#candidateCorrection = value;
|
|
422
|
-
const states = this.internals.states;
|
|
423
|
-
states.delete("candidate-correct");
|
|
424
|
-
states.delete("candidate-incorrect");
|
|
425
|
-
states.delete("candidate-partially-correct");
|
|
426
|
-
if (value)
|
|
427
|
-
states.add(`candidate-${value}`);
|
|
428
|
-
this.requestUpdate("candidateCorrection", previous);
|
|
429
|
-
}
|
|
430
|
-
get correctionPart() {
|
|
431
|
-
return this.#candidateCorrection ? `correction correction-${this.#candidateCorrection}` : "correction";
|
|
159
|
+
updated() {
|
|
160
|
+
if (!this.#hasCorrectResponse || this.#previousActiveItem !== this.computedContext?.identifier) {
|
|
161
|
+
this.#previousActiveItem = this.computedContext?.identifier;
|
|
162
|
+
const containsCorrectResponse = !!this.computedContext?.variables.some((v) => v["correctResponse"]);
|
|
163
|
+
const containsMapping = !!this.computedContext?.variables.some((v) => {
|
|
164
|
+
return v["mapping"]?.mapEntries?.length > 0 || v["areaMapping"]?.areaMapEntries?.length > 0;
|
|
165
|
+
});
|
|
166
|
+
this.#hasCorrectResponse = containsCorrectResponse || containsMapping;
|
|
432
167
|
}
|
|
168
|
+
this.disabled = !this.#hasCorrectResponse;
|
|
433
169
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
170
|
+
#toggleState() {
|
|
171
|
+
if (this.disabled)
|
|
172
|
+
return;
|
|
173
|
+
this.dispatchEvent(new CustomEvent("item-show-candidate-correction", {
|
|
174
|
+
detail: !this.shown,
|
|
175
|
+
bubbles: true
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
#getDisplayedText() {
|
|
179
|
+
return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCandidateCorrectionText : this.showCandidateCorrectionText;
|
|
441
180
|
}
|
|
442
181
|
render() {
|
|
443
|
-
return
|
|
444
|
-
<slot part="label"></slot>
|
|
445
|
-
<span part=${this.correctionPart} aria-hidden="true"></span>`;
|
|
182
|
+
return html2` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
|
|
446
183
|
}
|
|
447
184
|
};
|
|
185
|
+
__decorate2([
|
|
186
|
+
consume2({ context: computedItemContext, subscribe: true })
|
|
187
|
+
], ItemShowCandidateCorrection.prototype, "computedContext", void 0);
|
|
188
|
+
__decorate2([
|
|
189
|
+
property2({ type: Boolean, reflect: true })
|
|
190
|
+
], ItemShowCandidateCorrection.prototype, "shown", void 0);
|
|
191
|
+
__decorate2([
|
|
192
|
+
property2({ type: Boolean, reflect: true })
|
|
193
|
+
], ItemShowCandidateCorrection.prototype, "disabled", void 0);
|
|
194
|
+
__decorate2([
|
|
195
|
+
property2({ type: String })
|
|
196
|
+
], ItemShowCandidateCorrection.prototype, "showCandidateCorrectionText", void 0);
|
|
197
|
+
__decorate2([
|
|
198
|
+
property2({ type: String })
|
|
199
|
+
], ItemShowCandidateCorrection.prototype, "hideCandidateCorrectionText", void 0);
|
|
200
|
+
__decorate2([
|
|
201
|
+
property2({ type: String })
|
|
202
|
+
], ItemShowCandidateCorrection.prototype, "noCorrectResponseText", void 0);
|
|
448
203
|
|
|
449
|
-
// ../qti-corrections/dist/
|
|
450
|
-
import {
|
|
204
|
+
// ../qti-corrections/dist/components/item-show-correct-response/item-show-correct-response.js
|
|
205
|
+
import { css as css3, html as html3, LitElement as LitElement3 } from "lit";
|
|
206
|
+
import { property as property3 } from "lit/decorators.js";
|
|
207
|
+
import { consume as consume3 } from "@lit/context";
|
|
451
208
|
var __decorate3 = function(decorators, target, key, desc) {
|
|
452
209
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
453
210
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
454
211
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
455
212
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
456
213
|
};
|
|
457
|
-
var
|
|
214
|
+
var ItemShowCorrectResponse = class extends LitElement3 {
|
|
458
215
|
constructor() {
|
|
459
216
|
super(...arguments);
|
|
460
|
-
this.
|
|
217
|
+
this.shown = false;
|
|
218
|
+
this.disabled = false;
|
|
219
|
+
this.showCorrectText = "Show correct response";
|
|
220
|
+
this.hideCorrectText = "Hide correct response";
|
|
221
|
+
this.noCorrectResponseText = "No correct response specified";
|
|
222
|
+
this.#hasCorrectResponse = false;
|
|
223
|
+
this.#previousActiveItem = "";
|
|
461
224
|
}
|
|
462
|
-
};
|
|
463
|
-
__decorate3([
|
|
464
|
-
property2({ attribute: "aria-ordercorrectvalue", type: Number, reflect: true })
|
|
465
|
-
], QtiHotspotChoiceCorrection.prototype, "orderCorrect", void 0);
|
|
466
|
-
|
|
467
|
-
// ../qti-corrections/dist/elements/qti-hottext-correction.js
|
|
468
|
-
import { html as html2 } from "lit";
|
|
469
|
-
var QtiHottextCorrection = class extends ActiveElementCorrectionMixin(QtiHottext) {
|
|
470
225
|
static {
|
|
471
|
-
this.styles =
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
226
|
+
this.styles = css3`
|
|
227
|
+
:host {
|
|
228
|
+
${btn};
|
|
229
|
+
}
|
|
230
|
+
:host([disabled]) {
|
|
231
|
+
${dis};
|
|
232
|
+
}
|
|
233
|
+
`;
|
|
477
234
|
}
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
235
|
+
#hasCorrectResponse;
|
|
236
|
+
// correct response is removed on certain point
|
|
237
|
+
#previousActiveItem;
|
|
238
|
+
// Store previous active item reference
|
|
239
|
+
updated() {
|
|
240
|
+
if (!this.#hasCorrectResponse || this.#previousActiveItem !== this.computedContext?.identifier) {
|
|
241
|
+
this.#previousActiveItem = this.computedContext?.identifier;
|
|
242
|
+
const containsCorrectResponse = !!this.computedContext?.variables.some((v) => v["correctResponse"]);
|
|
243
|
+
const containsMapping = !!this.computedContext?.variables.some((v) => {
|
|
244
|
+
return v["mapping"]?.mapEntries?.length > 0 || v["areaMapping"]?.areaMapEntries?.length > 0;
|
|
245
|
+
});
|
|
246
|
+
this.#hasCorrectResponse = containsCorrectResponse || containsMapping;
|
|
247
|
+
}
|
|
248
|
+
this.disabled = !this.#hasCorrectResponse;
|
|
486
249
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
</div>
|
|
495
|
-
`;
|
|
250
|
+
#toggleState() {
|
|
251
|
+
if (this.disabled)
|
|
252
|
+
return;
|
|
253
|
+
this.dispatchEvent(new CustomEvent("item-show-correct-response", {
|
|
254
|
+
detail: !this.shown,
|
|
255
|
+
bubbles: true
|
|
256
|
+
}));
|
|
496
257
|
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
// ../qti-corrections/dist/elements/qti-simple-choice-correction.js
|
|
500
|
-
import { html as html4, nothing } from "lit";
|
|
501
|
-
var QtiSimpleChoiceCorrection = class extends ActiveElementCorrectionMixin(QtiSimpleChoice) {
|
|
502
|
-
static {
|
|
503
|
-
this.styles = [QtiSimpleChoice.styles, correctionPart];
|
|
258
|
+
#getDisplayedText() {
|
|
259
|
+
return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCorrectText : this.showCorrectText;
|
|
504
260
|
}
|
|
505
261
|
render() {
|
|
506
|
-
return
|
|
507
|
-
${this.marker ? html4`<div id="label" part="marker">${this.marker}</div>` : nothing}
|
|
508
|
-
<slot part="label"></slot>
|
|
509
|
-
<span part=${this.correctionPart} aria-hidden="true"></span>`;
|
|
262
|
+
return html3` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
|
|
510
263
|
}
|
|
511
264
|
};
|
|
265
|
+
__decorate3([
|
|
266
|
+
consume3({ context: computedItemContext, subscribe: true })
|
|
267
|
+
], ItemShowCorrectResponse.prototype, "computedContext", void 0);
|
|
268
|
+
__decorate3([
|
|
269
|
+
property3({ type: Boolean, reflect: true })
|
|
270
|
+
], ItemShowCorrectResponse.prototype, "shown", void 0);
|
|
271
|
+
__decorate3([
|
|
272
|
+
property3({ type: Boolean, reflect: true })
|
|
273
|
+
], ItemShowCorrectResponse.prototype, "disabled", void 0);
|
|
274
|
+
__decorate3([
|
|
275
|
+
property3({ type: String })
|
|
276
|
+
], ItemShowCorrectResponse.prototype, "showCorrectText", void 0);
|
|
277
|
+
__decorate3([
|
|
278
|
+
property3({ type: String })
|
|
279
|
+
], ItemShowCorrectResponse.prototype, "hideCorrectText", void 0);
|
|
280
|
+
__decorate3([
|
|
281
|
+
property3({ type: String })
|
|
282
|
+
], ItemShowCorrectResponse.prototype, "noCorrectResponseText", void 0);
|
|
512
283
|
|
|
513
|
-
// ../qti-corrections/dist/components/
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
284
|
+
// ../qti-corrections/dist/components/test-show-correct-response/test-show-correct-response.js
|
|
285
|
+
import { css as css4, html as html4, LitElement as LitElement4 } from "lit";
|
|
286
|
+
import { property as property4 } from "lit/decorators.js";
|
|
287
|
+
import { consume as consume4 } from "@lit/context";
|
|
288
|
+
var __decorate4 = function(decorators, target, key, desc) {
|
|
289
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
290
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
291
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
292
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
293
|
+
};
|
|
294
|
+
var TestShowCorrectResponse = class extends LitElement4 {
|
|
295
|
+
constructor() {
|
|
296
|
+
super(...arguments);
|
|
297
|
+
this.shown = false;
|
|
298
|
+
this.disabled = false;
|
|
299
|
+
this.showCorrectText = "Show correct response";
|
|
300
|
+
this.hideCorrectText = "Hide correct response";
|
|
301
|
+
this.noCorrectResponseText = "No correct response specified";
|
|
520
302
|
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
303
|
+
static {
|
|
304
|
+
this.styles = css4`
|
|
305
|
+
:host {
|
|
306
|
+
${btn};
|
|
524
307
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
308
|
+
:host([disabled]) {
|
|
309
|
+
${dis};
|
|
310
|
+
}
|
|
311
|
+
`;
|
|
529
312
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
313
|
+
#previousActiveItem;
|
|
314
|
+
// Store previous active item reference
|
|
315
|
+
willUpdate(_changedProperties) {
|
|
316
|
+
const activeItem = this.computedContext?.testParts.flatMap((testPart) => testPart.sections.flatMap((section) => section.items)).find((item) => item.active);
|
|
317
|
+
if (this.#previousActiveItem !== activeItem) {
|
|
318
|
+
this.shown = false;
|
|
319
|
+
this.#previousActiveItem = activeItem;
|
|
320
|
+
}
|
|
321
|
+
if (activeItem) {
|
|
322
|
+
const containsCorrectResponse = !!activeItem?.variables?.some((v) => v["correctResponse"]);
|
|
323
|
+
const containsMapping = !!activeItem?.variables?.some((v) => {
|
|
324
|
+
return v["mapping"]?.mapEntries?.length > 0 || v["areaMapping"]?.areaMapEntries?.length > 0;
|
|
325
|
+
});
|
|
326
|
+
this.disabled = !containsCorrectResponse && !containsMapping;
|
|
327
|
+
} else {
|
|
328
|
+
this.disabled = true;
|
|
537
329
|
}
|
|
538
330
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
};
|
|
548
|
-
#onShowCandidateCorrection = (event) => {
|
|
549
|
-
const show = event.detail;
|
|
550
|
-
this.assessmentItem?.showCandidateCorrection?.(show);
|
|
551
|
-
this.updateControlState("item-show-candidate-correction", show);
|
|
552
|
-
};
|
|
553
|
-
#onSwitchCorrectResponseMode = (event) => {
|
|
554
|
-
this.assessmentItem?.showCorrectResponse?.(false);
|
|
555
|
-
this.configContext = {
|
|
556
|
-
...this.configContext,
|
|
557
|
-
correctResponseMode: event.detail
|
|
558
|
-
};
|
|
559
|
-
};
|
|
560
|
-
constructor() {
|
|
561
|
-
super();
|
|
562
|
-
this.addEventListener("item-show-correct-response", this.#onShowCorrectResponse);
|
|
563
|
-
this.addEventListener("item-show-candidate-correction", this.#onShowCandidateCorrection);
|
|
564
|
-
this.addEventListener("item-switch-correct-response-mode", this.#onSwitchCorrectResponseMode);
|
|
331
|
+
#toggleState() {
|
|
332
|
+
if (this.disabled)
|
|
333
|
+
return;
|
|
334
|
+
this.shown = !this.shown;
|
|
335
|
+
this.dispatchEvent(new CustomEvent("test-show-correct-response", {
|
|
336
|
+
detail: this.shown,
|
|
337
|
+
bubbles: true
|
|
338
|
+
}));
|
|
565
339
|
}
|
|
566
|
-
|
|
567
|
-
this.
|
|
340
|
+
#getDisplayedText() {
|
|
341
|
+
return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCorrectText : this.showCorrectText;
|
|
568
342
|
}
|
|
569
|
-
|
|
570
|
-
this
|
|
571
|
-
this.removeEventListener("item-show-candidate-correction", this.#onShowCandidateCorrection);
|
|
572
|
-
this.removeEventListener("item-switch-correct-response-mode", this.#onSwitchCorrectResponseMode);
|
|
573
|
-
super.disconnectedCallback();
|
|
343
|
+
render() {
|
|
344
|
+
return html4` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
|
|
574
345
|
}
|
|
575
346
|
};
|
|
347
|
+
__decorate4([
|
|
348
|
+
consume4({ context: computedContext, subscribe: true })
|
|
349
|
+
], TestShowCorrectResponse.prototype, "computedContext", void 0);
|
|
350
|
+
__decorate4([
|
|
351
|
+
property4({ type: Boolean, reflect: true })
|
|
352
|
+
], TestShowCorrectResponse.prototype, "shown", void 0);
|
|
353
|
+
__decorate4([
|
|
354
|
+
property4({ type: Boolean, reflect: true })
|
|
355
|
+
], TestShowCorrectResponse.prototype, "disabled", void 0);
|
|
356
|
+
__decorate4([
|
|
357
|
+
property4({ type: String })
|
|
358
|
+
], TestShowCorrectResponse.prototype, "showCorrectText", void 0);
|
|
359
|
+
__decorate4([
|
|
360
|
+
property4({ type: String })
|
|
361
|
+
], TestShowCorrectResponse.prototype, "hideCorrectText", void 0);
|
|
362
|
+
__decorate4([
|
|
363
|
+
property4({ type: String })
|
|
364
|
+
], TestShowCorrectResponse.prototype, "noCorrectResponseText", void 0);
|
|
576
365
|
|
|
577
|
-
// ../qti-corrections/dist/
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
this.activeAssessmentItem?.showCandidateCorrection?.(event.detail);
|
|
584
|
-
};
|
|
585
|
-
constructor() {
|
|
586
|
-
super();
|
|
587
|
-
this.addEventListener("test-show-correct-response", this.#onShowCorrectResponse);
|
|
588
|
-
this.addEventListener("test-show-candidate-correction", this.#onShowCandidateCorrection);
|
|
366
|
+
// ../qti-corrections/dist/styles/correction.styles.js
|
|
367
|
+
import { css as css5 } from "lit";
|
|
368
|
+
var correctionPart = css5`
|
|
369
|
+
/* Nothing at all until the item judges this element. */
|
|
370
|
+
[part~='correction'] {
|
|
371
|
+
display: none;
|
|
589
372
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
373
|
+
|
|
374
|
+
[part~='correction-correct'],
|
|
375
|
+
[part~='correction-incorrect'],
|
|
376
|
+
[part~='correction-partially-correct'] {
|
|
377
|
+
display: inline-flex;
|
|
378
|
+
flex: 0 0 auto;
|
|
379
|
+
|
|
380
|
+
/*
|
|
381
|
+
* The badge aligns ITSELF, and that is the whole of the vertical story.
|
|
382
|
+
*
|
|
383
|
+
* It is a flex item with a definite height, so left alone its cross-axis position is decided by
|
|
384
|
+
* whatever its host says — and the hosts disagree: qti-simple-associable-choice defaults to
|
|
385
|
+
* align-items: normal, and qti-gap-text gates center behind :not([part~='drag']), so the
|
|
386
|
+
* same chip centred its badge in the bank and top-aligned it once placed. align-self settles it
|
|
387
|
+
* from the badge's side, in one line, without touching a single container.
|
|
388
|
+
*
|
|
389
|
+
* This replaces an align-items/justify-content: center pair that had never done anything: the
|
|
390
|
+
* badge is empty — a mask painted over a background — so centring its CONTENTS centres nothing.
|
|
391
|
+
*/
|
|
392
|
+
align-self: center;
|
|
393
|
+
|
|
394
|
+
box-sizing: border-box;
|
|
395
|
+
width: var(--qti-correction-size, 1em);
|
|
396
|
+
height: var(--qti-correction-size, 1em);
|
|
397
|
+
margin-left: var(--qti-glyph-gap, 0.5em);
|
|
398
|
+
|
|
399
|
+
pointer-events: none;
|
|
594
400
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
401
|
+
`;
|
|
402
|
+
|
|
403
|
+
// ../qti-corrections/dist/elements/qti-gap-text-correction.js
|
|
404
|
+
import { html as html5 } from "lit";
|
|
405
|
+
|
|
406
|
+
// ../qti-corrections/dist/mixins/active-element-correction.mixin.js
|
|
407
|
+
var ActiveElementCorrectionMixin = (superClass) => {
|
|
408
|
+
class ActiveElementCorrectionMixinClass extends superClass {
|
|
409
|
+
#candidateCorrection = null;
|
|
410
|
+
get candidateCorrection() {
|
|
411
|
+
return this.#candidateCorrection;
|
|
412
|
+
}
|
|
413
|
+
set candidateCorrection(value) {
|
|
414
|
+
if (this.#candidateCorrection === value)
|
|
415
|
+
return;
|
|
416
|
+
const previous = this.#candidateCorrection;
|
|
417
|
+
this.#candidateCorrection = value;
|
|
418
|
+
const states = this.internals.states;
|
|
419
|
+
states.delete("candidate-correct");
|
|
420
|
+
states.delete("candidate-incorrect");
|
|
421
|
+
states.delete("candidate-partially-correct");
|
|
422
|
+
if (value)
|
|
423
|
+
states.add(`candidate-${value}`);
|
|
424
|
+
this.requestUpdate("candidateCorrection", previous);
|
|
425
|
+
}
|
|
426
|
+
get correctionPart() {
|
|
427
|
+
return this.#candidateCorrection ? `correction correction-${this.#candidateCorrection}` : "correction";
|
|
428
|
+
}
|
|
610
429
|
}
|
|
430
|
+
return ActiveElementCorrectionMixinClass;
|
|
611
431
|
};
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
432
|
+
|
|
433
|
+
// ../qti-corrections/dist/elements/qti-gap-text-correction.js
|
|
434
|
+
var QtiGapTextCorrection = class extends ActiveElementCorrectionMixin(QtiGapText) {
|
|
435
|
+
static {
|
|
436
|
+
this.styles = [QtiGapText.styles, correctionPart];
|
|
615
437
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
this.addEventListener("click", () => {
|
|
621
|
-
this.dispatchEvent(new CustomEvent("test-show-correct-response", { detail: true, bubbles: true }));
|
|
622
|
-
});
|
|
438
|
+
render() {
|
|
439
|
+
return html5`<div part="control"></div>
|
|
440
|
+
<slot part="label"></slot>
|
|
441
|
+
<span part=${this.correctionPart} aria-hidden="true"></span>`;
|
|
623
442
|
}
|
|
624
443
|
};
|
|
625
444
|
|
|
626
|
-
// ../qti-corrections/dist/
|
|
627
|
-
import {
|
|
628
|
-
|
|
629
|
-
import { consume } from "@lit/context";
|
|
630
|
-
var __decorate4 = function(decorators, target, key, desc) {
|
|
445
|
+
// ../qti-corrections/dist/elements/qti-hotspot-choice-correction.js
|
|
446
|
+
import { property as property5 } from "lit/decorators.js";
|
|
447
|
+
var __decorate5 = function(decorators, target, key, desc) {
|
|
631
448
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
632
449
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
633
450
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
634
451
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
635
452
|
};
|
|
636
|
-
var
|
|
453
|
+
var QtiHotspotChoiceCorrection = class extends ActiveElementCorrectionMixin(QtiHotspotChoice) {
|
|
637
454
|
constructor() {
|
|
638
455
|
super(...arguments);
|
|
639
|
-
this.
|
|
640
|
-
this._options = {
|
|
641
|
-
internal: "Internal",
|
|
642
|
-
full: "Full (copy)"
|
|
643
|
-
};
|
|
456
|
+
this.orderCorrect = null;
|
|
644
457
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
458
|
+
};
|
|
459
|
+
__decorate5([
|
|
460
|
+
property5({ attribute: "aria-ordercorrectvalue", type: Number, reflect: true })
|
|
461
|
+
], QtiHotspotChoiceCorrection.prototype, "orderCorrect", void 0);
|
|
462
|
+
|
|
463
|
+
// ../qti-corrections/dist/elements/qti-hottext-correction.js
|
|
464
|
+
import { html as html6 } from "lit";
|
|
465
|
+
var QtiHottextCorrection = class extends ActiveElementCorrectionMixin(QtiHottext) {
|
|
466
|
+
static {
|
|
467
|
+
this.styles = [QtiHottext.styles, correctionPart];
|
|
650
468
|
}
|
|
651
469
|
render() {
|
|
652
|
-
return
|
|
653
|
-
<
|
|
654
|
-
<
|
|
655
|
-
part="select"
|
|
656
|
-
id="modeSelect"
|
|
657
|
-
@change=${(e) => {
|
|
658
|
-
const el = e.target;
|
|
659
|
-
this.#switchMode(el.value);
|
|
660
|
-
}}
|
|
661
|
-
>
|
|
662
|
-
${Object.keys(this._options).map((value) => html5`<option value="${value}" ?selected=${value === this.itemContext?.correctResponseMode}>
|
|
663
|
-
${this._options[value]}
|
|
664
|
-
</option>`)}
|
|
665
|
-
</select>
|
|
666
|
-
`;
|
|
470
|
+
return html6`<div part="control"><div part="control-mark"></div></div>
|
|
471
|
+
<slot part="label"></slot>
|
|
472
|
+
<span part=${this.correctionPart} aria-hidden="true"></span>`;
|
|
667
473
|
}
|
|
668
474
|
};
|
|
669
|
-
__decorate4([
|
|
670
|
-
consume({ context: configContext, subscribe: true })
|
|
671
|
-
], ItemCorrectResponseMode.prototype, "itemContext", void 0);
|
|
672
|
-
__decorate4([
|
|
673
|
-
property3({ type: String })
|
|
674
|
-
], ItemCorrectResponseMode.prototype, "label", void 0);
|
|
675
|
-
__decorate4([
|
|
676
|
-
state3()
|
|
677
|
-
], ItemCorrectResponseMode.prototype, "_options", void 0);
|
|
678
475
|
|
|
679
|
-
// ../qti-corrections/dist/
|
|
680
|
-
import {
|
|
681
|
-
import {
|
|
682
|
-
|
|
476
|
+
// ../qti-corrections/dist/elements/qti-simple-associable-choice-correction.js
|
|
477
|
+
import { html as html7 } from "lit";
|
|
478
|
+
import { repeat } from "lit/directives/repeat.js";
|
|
479
|
+
var QtiSimpleAssociableChoiceCorrection = class extends ActiveElementCorrectionMixin(QtiSimpleAssociableChoice) {
|
|
480
|
+
static {
|
|
481
|
+
this.styles = [QtiSimpleAssociableChoice.styles, correctionPart];
|
|
482
|
+
}
|
|
483
|
+
render() {
|
|
484
|
+
return html7`
|
|
485
|
+
<div part="control"></div>
|
|
486
|
+
<slot part="label"></slot>
|
|
487
|
+
<span part=${this.correctionPart} aria-hidden="true"></span>
|
|
488
|
+
<div part="drop">
|
|
489
|
+
${repeat(this.drags, (node) => node.getAttribute("identifier"), (node) => node)}
|
|
490
|
+
</div>
|
|
491
|
+
`;
|
|
492
|
+
}
|
|
493
|
+
};
|
|
683
494
|
|
|
684
|
-
// ../qti-corrections/dist/
|
|
685
|
-
import {
|
|
686
|
-
var
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
`;
|
|
698
|
-
var dis = css2`
|
|
699
|
-
cursor: not-allowed;
|
|
700
|
-
opacity: 0.8;
|
|
701
|
-
`;
|
|
702
|
-
var ind = css2`
|
|
703
|
-
${form};
|
|
704
|
-
border: 1px solid gray;
|
|
705
|
-
`;
|
|
495
|
+
// ../qti-corrections/dist/elements/qti-simple-choice-correction.js
|
|
496
|
+
import { html as html8, nothing } from "lit";
|
|
497
|
+
var QtiSimpleChoiceCorrection = class extends ActiveElementCorrectionMixin(QtiSimpleChoice) {
|
|
498
|
+
static {
|
|
499
|
+
this.styles = [QtiSimpleChoice.styles, correctionPart];
|
|
500
|
+
}
|
|
501
|
+
render() {
|
|
502
|
+
return html8`<div part="control" tabindex="0"><div part="control-mark"></div></div>
|
|
503
|
+
${this.marker ? html8`<div id="label" part="marker">${this.marker}</div>` : nothing}
|
|
504
|
+
<slot part="label"></slot>
|
|
505
|
+
<span part=${this.correctionPart} aria-hidden="true"></span>`;
|
|
506
|
+
}
|
|
507
|
+
};
|
|
706
508
|
|
|
707
|
-
// ../qti-corrections/dist/
|
|
708
|
-
|
|
509
|
+
// ../qti-corrections/dist/mixins/correct-response.mixin.js
|
|
510
|
+
import { property as property6, state as state2 } from "lit/decorators.js";
|
|
511
|
+
var __decorate6 = function(decorators, target, key, desc) {
|
|
709
512
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
710
513
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
711
514
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
712
515
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
713
516
|
};
|
|
714
|
-
var
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
517
|
+
var Correctness;
|
|
518
|
+
(function(Correctness2) {
|
|
519
|
+
Correctness2["Correct"] = "correct";
|
|
520
|
+
Correctness2["PartiallyCorrect"] = "partially-correct";
|
|
521
|
+
Correctness2["Incorrect"] = "incorrect";
|
|
522
|
+
})(Correctness || (Correctness = {}));
|
|
523
|
+
var CorrectResponseMixin = (superClass) => {
|
|
524
|
+
class CorrectResponseMixinClass extends superClass {
|
|
525
|
+
constructor() {
|
|
526
|
+
super(...arguments);
|
|
527
|
+
this.showCorrectResponse = false;
|
|
528
|
+
this._handleShowCorrectResponseChange = (_, show) => {
|
|
529
|
+
this.toggleInternalCorrectResponse(show);
|
|
530
|
+
};
|
|
531
|
+
this.showFullCorrectResponse = false;
|
|
532
|
+
this._handleShowFullCorrectResponseChange = (_, show) => {
|
|
533
|
+
this.toggleFullCorrectResponse(show);
|
|
534
|
+
};
|
|
535
|
+
this.showCandidateCorrection = false;
|
|
536
|
+
this._handleShowCandidateCorrectionChange = (_, show) => {
|
|
537
|
+
this.toggleCandidateCorrection(show);
|
|
538
|
+
};
|
|
539
|
+
this._correctResponse = null;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* The correct response for this interaction. Can be set as a comma-separated
|
|
543
|
+
* string via attribute or as string/string[] via property.
|
|
544
|
+
*
|
|
545
|
+
* @example
|
|
546
|
+
* ```html
|
|
547
|
+
* <qti-choice-interaction correct-response="A,B">
|
|
548
|
+
* ```
|
|
549
|
+
*/
|
|
550
|
+
set correctResponseAttr(val) {
|
|
551
|
+
this._correctResponse = val;
|
|
552
|
+
}
|
|
553
|
+
get correctResponseAttr() {
|
|
554
|
+
return this._correctResponse;
|
|
555
|
+
}
|
|
556
|
+
get isFullCorrectResponse() {
|
|
557
|
+
return this._isFullCorrectResponse;
|
|
558
|
+
}
|
|
559
|
+
get registersWithItem() {
|
|
560
|
+
return !this.isFullCorrectResponse && super.registersWithItem;
|
|
561
|
+
}
|
|
562
|
+
set isFullCorrectResponse(val) {
|
|
563
|
+
this._isFullCorrectResponse = val;
|
|
564
|
+
if (val) {
|
|
565
|
+
this.setAttribute("inert", "");
|
|
566
|
+
this.setAttribute("response-identifier", this.responseIdentifier + "_cr");
|
|
567
|
+
this.setAttribute("answer-key", "");
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
get correctResponse() {
|
|
571
|
+
const responseVariable = this.responseVariable;
|
|
572
|
+
if (responseVariable?.correctResponse) {
|
|
573
|
+
return responseVariable.correctResponse;
|
|
574
|
+
}
|
|
575
|
+
return this._correctResponse;
|
|
576
|
+
}
|
|
577
|
+
set correctResponse(val) {
|
|
578
|
+
const oldVal = this._correctResponse;
|
|
579
|
+
this._correctResponse = val;
|
|
580
|
+
if (val === null || val === void 0) {
|
|
581
|
+
this.removeAttribute("correct-response");
|
|
582
|
+
} else {
|
|
583
|
+
this.setAttribute("correct-response", Array.isArray(val) ? val.join(",") : val);
|
|
584
|
+
}
|
|
585
|
+
this.requestUpdate("_correctResponse", oldVal);
|
|
586
|
+
}
|
|
587
|
+
// ─── correctness getter ───────────────────────────────────────────────────
|
|
588
|
+
get correctness() {
|
|
589
|
+
const correctResponse = this.correctResponse;
|
|
590
|
+
if (!correctResponse)
|
|
591
|
+
return null;
|
|
592
|
+
const currentResponse = this.response;
|
|
593
|
+
if (currentResponse === null || currentResponse === void 0 || currentResponse === "" || Array.isArray(currentResponse) && currentResponse.length === 0) {
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
const correctArr = Array.isArray(correctResponse) ? correctResponse : [correctResponse];
|
|
597
|
+
const responseArr = Array.isArray(currentResponse) ? currentResponse : [currentResponse];
|
|
598
|
+
const filteredResponseArr = responseArr.filter((r) => r !== "");
|
|
599
|
+
if (filteredResponseArr.length === 0)
|
|
600
|
+
return null;
|
|
601
|
+
const correctCount = filteredResponseArr.filter((r) => correctArr.includes(r)).length;
|
|
602
|
+
const incorrectCount = filteredResponseArr.filter((r) => !correctArr.includes(r)).length;
|
|
603
|
+
if (correctCount === correctArr.length && incorrectCount === 0 && filteredResponseArr.length === correctArr.length) {
|
|
604
|
+
return Correctness.Correct;
|
|
605
|
+
}
|
|
606
|
+
if (correctCount > 0 && (correctCount < correctArr.length || incorrectCount > 0)) {
|
|
607
|
+
return Correctness.PartiallyCorrect;
|
|
608
|
+
}
|
|
609
|
+
return Correctness.Incorrect;
|
|
719
610
|
}
|
|
720
|
-
|
|
721
|
-
|
|
611
|
+
// ─── correctionPart ───────────────────────────────────────────────────────
|
|
612
|
+
get correctionPart() {
|
|
613
|
+
return "correction";
|
|
722
614
|
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
this.disabled = false;
|
|
733
|
-
this.showCandidateCorrectionText = "Show candidate correction";
|
|
734
|
-
this.hideCandidateCorrectionText = "Hide candidate correction";
|
|
735
|
-
this.noCorrectResponseText = "No correct response specified";
|
|
736
|
-
this.#hasCorrectResponse = false;
|
|
737
|
-
this.#previousActiveItem = "";
|
|
738
|
-
}
|
|
739
|
-
updated() {
|
|
740
|
-
if (!this.#hasCorrectResponse || this.#previousActiveItem !== this.computedContext?.identifier) {
|
|
741
|
-
this.#previousActiveItem = this.computedContext?.identifier;
|
|
742
|
-
const containsCorrectResponse = !!this.computedContext?.variables.some((v) => v["correctResponse"]);
|
|
743
|
-
const containsMapping = !!this.computedContext?.variables.some((v) => {
|
|
744
|
-
return v["mapping"]?.mapEntries?.length > 0 || v["areaMapping"]?.areaMapEntries?.length > 0;
|
|
745
|
-
});
|
|
746
|
-
this.#hasCorrectResponse = containsCorrectResponse || containsMapping;
|
|
615
|
+
// ─── toggle methods ───────────────────────────────────────────────────────
|
|
616
|
+
toggleCorrectResponse(show) {
|
|
617
|
+
const correctionConfig = this.configContext;
|
|
618
|
+
const correctResponseMode = correctionConfig?.correctResponseMode || "internal";
|
|
619
|
+
if (correctResponseMode === "full") {
|
|
620
|
+
this.toggleFullCorrectResponse(show);
|
|
621
|
+
} else {
|
|
622
|
+
this.toggleInternalCorrectResponse(show);
|
|
623
|
+
}
|
|
747
624
|
}
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
render() {
|
|
762
|
-
return html6` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
|
|
763
|
-
}
|
|
764
|
-
};
|
|
765
|
-
__decorate5([
|
|
766
|
-
consume2({ context: computedItemContext, subscribe: true })
|
|
767
|
-
], ItemShowCandidateCorrection.prototype, "computedContext", void 0);
|
|
768
|
-
__decorate5([
|
|
769
|
-
property4({ type: Boolean, reflect: true })
|
|
770
|
-
], ItemShowCandidateCorrection.prototype, "shown", void 0);
|
|
771
|
-
__decorate5([
|
|
772
|
-
property4({ type: Boolean, reflect: true })
|
|
773
|
-
], ItemShowCandidateCorrection.prototype, "disabled", void 0);
|
|
774
|
-
__decorate5([
|
|
775
|
-
property4({ type: String })
|
|
776
|
-
], ItemShowCandidateCorrection.prototype, "showCandidateCorrectionText", void 0);
|
|
777
|
-
__decorate5([
|
|
778
|
-
property4({ type: String })
|
|
779
|
-
], ItemShowCandidateCorrection.prototype, "hideCandidateCorrectionText", void 0);
|
|
780
|
-
__decorate5([
|
|
781
|
-
property4({ type: String })
|
|
782
|
-
], ItemShowCandidateCorrection.prototype, "noCorrectResponseText", void 0);
|
|
783
|
-
|
|
784
|
-
// ../qti-corrections/dist/components/item-show-correct-response/item-show-correct-response.js
|
|
785
|
-
import { css as css4, html as html7, LitElement as LitElement3 } from "lit";
|
|
786
|
-
import { property as property5 } from "lit/decorators.js";
|
|
787
|
-
import { consume as consume3 } from "@lit/context";
|
|
788
|
-
var __decorate6 = function(decorators, target, key, desc) {
|
|
789
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
790
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
791
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
792
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
793
|
-
};
|
|
794
|
-
var ItemShowCorrectResponse = class extends LitElement3 {
|
|
795
|
-
constructor() {
|
|
796
|
-
super(...arguments);
|
|
797
|
-
this.shown = false;
|
|
798
|
-
this.disabled = false;
|
|
799
|
-
this.showCorrectText = "Show correct response";
|
|
800
|
-
this.hideCorrectText = "Hide correct response";
|
|
801
|
-
this.noCorrectResponseText = "No correct response specified";
|
|
802
|
-
this.#hasCorrectResponse = false;
|
|
803
|
-
this.#previousActiveItem = "";
|
|
804
|
-
}
|
|
805
|
-
static {
|
|
806
|
-
this.styles = css4`
|
|
807
|
-
:host {
|
|
808
|
-
${btn};
|
|
625
|
+
/**
|
|
626
|
+
* Whether the full correct response is withheld from a candidate who is already correct.
|
|
627
|
+
*
|
|
628
|
+
* Withheld by default, unless the item configures `fullCorrectResponseOnlyWhenIncorrect: false`
|
|
629
|
+
* — the behaviour `show-full-correct-response` has always had, on the reasoning that a correct
|
|
630
|
+
* answer already *is* the key.
|
|
631
|
+
*
|
|
632
|
+
* An interaction that routes its internal mode here overrides this to false: there, the caller
|
|
633
|
+
* asked to show the correct response, and silently showing nothing is worse than showing the
|
|
634
|
+
* candidate the answer they already gave.
|
|
635
|
+
*/
|
|
636
|
+
get withholdsFullCorrectResponseWhenCorrect() {
|
|
637
|
+
return this.configContext?.fullCorrectResponseOnlyWhenIncorrect !== false;
|
|
809
638
|
}
|
|
810
|
-
|
|
811
|
-
|
|
639
|
+
async toggleFullCorrectResponse(show) {
|
|
640
|
+
const nextSibling = this.nextSibling;
|
|
641
|
+
const nextSiblingIsFullCorrectResponse = nextSibling instanceof HTMLDivElement && nextSibling?.classList.contains("full-correct-response");
|
|
642
|
+
const correctResponse = this.correctResponse;
|
|
643
|
+
if (!correctResponse) {
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
const showFullCorrectResponse = show && (!this.withholdsFullCorrectResponseWhenCorrect || this.correctness !== Correctness.Correct);
|
|
647
|
+
if (!showFullCorrectResponse) {
|
|
648
|
+
if (!nextSiblingIsFullCorrectResponse) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
this.parentElement?.removeChild(nextSibling);
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
if (nextSiblingIsFullCorrectResponse) {
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
const clone = this.cloneNode(true);
|
|
658
|
+
clone.removeAttribute("show-full-correct-response");
|
|
659
|
+
clone.removeAttribute("show-correct-response");
|
|
660
|
+
clone.removeAttribute("show-candidate-correction");
|
|
661
|
+
const containerDiv = document.createElement("div");
|
|
662
|
+
containerDiv.classList.add("full-correct-response");
|
|
663
|
+
if (this.isInline) {
|
|
664
|
+
containerDiv.classList.add("full-correct-response-inline");
|
|
665
|
+
} else {
|
|
666
|
+
containerDiv.classList.add("full-correct-response-block");
|
|
667
|
+
}
|
|
668
|
+
containerDiv.role = "full-correct-response";
|
|
669
|
+
containerDiv.appendChild(clone);
|
|
670
|
+
clone.isFullCorrectResponse = true;
|
|
671
|
+
this.parentElement?.insertBefore(containerDiv, this.nextSibling);
|
|
672
|
+
await clone.updateComplete;
|
|
673
|
+
clone.response = Array.isArray(correctResponse) ? [...correctResponse] : correctResponse;
|
|
812
674
|
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
675
|
+
toggleInternalCorrectResponse(show) {
|
|
676
|
+
this._internals.states.delete("show-correct-response");
|
|
677
|
+
if (show && this.correctResponse) {
|
|
678
|
+
this._internals.states.add("show-correct-response");
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
toggleCandidateCorrection(show) {
|
|
682
|
+
if (!show) {
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
// ─── Lifecycle ────────────────────────────────────────────────────────────
|
|
687
|
+
firstUpdated() {
|
|
688
|
+
super.firstUpdated();
|
|
689
|
+
if (this.isFullCorrectResponse) {
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
if (this.showCorrectResponse) {
|
|
693
|
+
this.toggleInternalCorrectResponse(true);
|
|
694
|
+
}
|
|
695
|
+
if (this.showFullCorrectResponse) {
|
|
696
|
+
this.toggleFullCorrectResponse(true);
|
|
697
|
+
}
|
|
827
698
|
}
|
|
828
|
-
this.disabled = !this.#hasCorrectResponse;
|
|
829
|
-
}
|
|
830
|
-
#toggleState() {
|
|
831
|
-
if (this.disabled)
|
|
832
|
-
return;
|
|
833
|
-
this.dispatchEvent(new CustomEvent("item-show-correct-response", {
|
|
834
|
-
detail: !this.shown,
|
|
835
|
-
bubbles: true
|
|
836
|
-
}));
|
|
837
|
-
}
|
|
838
|
-
#getDisplayedText() {
|
|
839
|
-
return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCorrectText : this.showCorrectText;
|
|
840
|
-
}
|
|
841
|
-
render() {
|
|
842
|
-
return html7` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
|
|
843
699
|
}
|
|
700
|
+
__decorate6([
|
|
701
|
+
property6({
|
|
702
|
+
attribute: "correct-response",
|
|
703
|
+
reflect: true,
|
|
704
|
+
converter: responseAttributeConverter({ emptyAs: null })
|
|
705
|
+
})
|
|
706
|
+
], CorrectResponseMixinClass.prototype, "correctResponseAttr", null);
|
|
707
|
+
__decorate6([
|
|
708
|
+
property6({ type: Boolean, attribute: "show-correct-response", reflect: true })
|
|
709
|
+
], CorrectResponseMixinClass.prototype, "showCorrectResponse", void 0);
|
|
710
|
+
__decorate6([
|
|
711
|
+
watch("showCorrectResponse", { waitUntilFirstUpdate: true })
|
|
712
|
+
], CorrectResponseMixinClass.prototype, "_handleShowCorrectResponseChange", void 0);
|
|
713
|
+
__decorate6([
|
|
714
|
+
property6({ type: Boolean, attribute: "show-full-correct-response", reflect: true })
|
|
715
|
+
], CorrectResponseMixinClass.prototype, "showFullCorrectResponse", void 0);
|
|
716
|
+
__decorate6([
|
|
717
|
+
watch("showFullCorrectResponse", { waitUntilFirstUpdate: true })
|
|
718
|
+
], CorrectResponseMixinClass.prototype, "_handleShowFullCorrectResponseChange", void 0);
|
|
719
|
+
__decorate6([
|
|
720
|
+
property6({ type: Boolean, attribute: "show-candidate-correction", reflect: true })
|
|
721
|
+
], CorrectResponseMixinClass.prototype, "showCandidateCorrection", void 0);
|
|
722
|
+
__decorate6([
|
|
723
|
+
watch("showCandidateCorrection", { waitUntilFirstUpdate: true })
|
|
724
|
+
], CorrectResponseMixinClass.prototype, "_handleShowCandidateCorrectionChange", void 0);
|
|
725
|
+
__decorate6([
|
|
726
|
+
state2()
|
|
727
|
+
], CorrectResponseMixinClass.prototype, "_isFullCorrectResponse", void 0);
|
|
728
|
+
__decorate6([
|
|
729
|
+
state2()
|
|
730
|
+
], CorrectResponseMixinClass.prototype, "_correctResponse", void 0);
|
|
731
|
+
return CorrectResponseMixinClass;
|
|
844
732
|
};
|
|
845
|
-
__decorate6([
|
|
846
|
-
consume3({ context: computedItemContext, subscribe: true })
|
|
847
|
-
], ItemShowCorrectResponse.prototype, "computedContext", void 0);
|
|
848
|
-
__decorate6([
|
|
849
|
-
property5({ type: Boolean, reflect: true })
|
|
850
|
-
], ItemShowCorrectResponse.prototype, "shown", void 0);
|
|
851
|
-
__decorate6([
|
|
852
|
-
property5({ type: Boolean, reflect: true })
|
|
853
|
-
], ItemShowCorrectResponse.prototype, "disabled", void 0);
|
|
854
|
-
__decorate6([
|
|
855
|
-
property5({ type: String })
|
|
856
|
-
], ItemShowCorrectResponse.prototype, "showCorrectText", void 0);
|
|
857
|
-
__decorate6([
|
|
858
|
-
property5({ type: String })
|
|
859
|
-
], ItemShowCorrectResponse.prototype, "hideCorrectText", void 0);
|
|
860
|
-
__decorate6([
|
|
861
|
-
property5({ type: String })
|
|
862
|
-
], ItemShowCorrectResponse.prototype, "noCorrectResponseText", void 0);
|
|
863
733
|
|
|
864
|
-
// ../qti-corrections/dist/
|
|
865
|
-
import {
|
|
866
|
-
import { property as property6 } from "lit/decorators.js";
|
|
867
|
-
import { consume as consume4 } from "@lit/context";
|
|
734
|
+
// ../qti-corrections/dist/mixins/candidate-correction.mixin.js
|
|
735
|
+
import { state as state3 } from "lit/decorators.js";
|
|
868
736
|
var __decorate7 = function(decorators, target, key, desc) {
|
|
869
737
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
870
738
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
871
739
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
872
740
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
873
741
|
};
|
|
874
|
-
var
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
this.showCorrectText = "Show correct response";
|
|
880
|
-
this.hideCorrectText = "Hide correct response";
|
|
881
|
-
this.noCorrectResponseText = "No correct response specified";
|
|
882
|
-
}
|
|
883
|
-
static {
|
|
884
|
-
this.styles = css5`
|
|
885
|
-
:host {
|
|
886
|
-
${btn};
|
|
742
|
+
var CandidateCorrectionMixin = (superClass) => {
|
|
743
|
+
class CandidateCorrectionMixinClass extends CorrectResponseMixin(superClass) {
|
|
744
|
+
constructor() {
|
|
745
|
+
super(...arguments);
|
|
746
|
+
this._candidateCorrection = null;
|
|
887
747
|
}
|
|
888
|
-
|
|
889
|
-
|
|
748
|
+
get correctionPart() {
|
|
749
|
+
return this._candidateCorrection ? `correction correction-${this._candidateCorrection}` : "correction";
|
|
890
750
|
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
751
|
+
toggleCandidateCorrection(show) {
|
|
752
|
+
if (this.showCandidateCorrection !== show) {
|
|
753
|
+
this.showCandidateCorrection = show;
|
|
754
|
+
}
|
|
755
|
+
super.toggleCandidateCorrection(show);
|
|
756
|
+
const internals = this._internals;
|
|
757
|
+
internals.states.delete("candidate-correct");
|
|
758
|
+
internals.states.delete("candidate-partially-correct");
|
|
759
|
+
internals.states.delete("candidate-incorrect");
|
|
760
|
+
let verdict = null;
|
|
761
|
+
if (show) {
|
|
762
|
+
if (this.correctness === Correctness.Correct) {
|
|
763
|
+
internals.states.add("candidate-correct");
|
|
764
|
+
verdict = "correct";
|
|
765
|
+
}
|
|
766
|
+
if (this.correctness === Correctness.PartiallyCorrect) {
|
|
767
|
+
internals.states.add("candidate-partially-correct");
|
|
768
|
+
verdict = "partially-correct";
|
|
769
|
+
}
|
|
770
|
+
if (this.correctness === Correctness.Incorrect) {
|
|
771
|
+
internals.states.add("candidate-incorrect");
|
|
772
|
+
verdict = "incorrect";
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
if (this._candidateCorrection !== verdict) {
|
|
776
|
+
this._candidateCorrection = verdict;
|
|
777
|
+
}
|
|
900
778
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
779
|
+
connectedCallback() {
|
|
780
|
+
super.connectedCallback?.();
|
|
781
|
+
queueMicrotask(() => {
|
|
782
|
+
if (!this.isConnected || this.isFullCorrectResponse) {
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
if (this.showCandidateCorrection) {
|
|
786
|
+
this.toggleCandidateCorrection(true);
|
|
787
|
+
}
|
|
905
788
|
});
|
|
906
|
-
this.disabled = !containsCorrectResponse && !containsMapping;
|
|
907
|
-
} else {
|
|
908
|
-
this.disabled = true;
|
|
909
789
|
}
|
|
910
790
|
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
this.dispatchEvent(new CustomEvent("test-show-correct-response", {
|
|
916
|
-
detail: this.shown,
|
|
917
|
-
bubbles: true
|
|
918
|
-
}));
|
|
919
|
-
}
|
|
920
|
-
#getDisplayedText() {
|
|
921
|
-
return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCorrectText : this.showCorrectText;
|
|
922
|
-
}
|
|
923
|
-
render() {
|
|
924
|
-
return html8` <div @click="${this.#toggleState}">${this.#getDisplayedText()}</div> `;
|
|
925
|
-
}
|
|
791
|
+
__decorate7([
|
|
792
|
+
state3()
|
|
793
|
+
], CandidateCorrectionMixinClass.prototype, "_candidateCorrection", void 0);
|
|
794
|
+
return CandidateCorrectionMixinClass;
|
|
926
795
|
};
|
|
927
|
-
__decorate7([
|
|
928
|
-
consume4({ context: computedContext, subscribe: true })
|
|
929
|
-
], TestShowCorrectResponse.prototype, "computedContext", void 0);
|
|
930
|
-
__decorate7([
|
|
931
|
-
property6({ type: Boolean, reflect: true })
|
|
932
|
-
], TestShowCorrectResponse.prototype, "shown", void 0);
|
|
933
|
-
__decorate7([
|
|
934
|
-
property6({ type: Boolean, reflect: true })
|
|
935
|
-
], TestShowCorrectResponse.prototype, "disabled", void 0);
|
|
936
|
-
__decorate7([
|
|
937
|
-
property6({ type: String })
|
|
938
|
-
], TestShowCorrectResponse.prototype, "showCorrectText", void 0);
|
|
939
|
-
__decorate7([
|
|
940
|
-
property6({ type: String })
|
|
941
|
-
], TestShowCorrectResponse.prototype, "hideCorrectText", void 0);
|
|
942
|
-
__decorate7([
|
|
943
|
-
property6({ type: String })
|
|
944
|
-
], TestShowCorrectResponse.prototype, "noCorrectResponseText", void 0);
|
|
945
796
|
|
|
946
797
|
// ../qti-corrections/dist/mixins/drag-drop-correction.mixin.js
|
|
947
798
|
var DragDropCorrectionMixin = (superClass) => {
|
|
@@ -968,6 +819,42 @@ var DragDropCorrectionMixin = (superClass) => {
|
|
|
968
819
|
var QtiAssociateInteractionCorrection = class extends DragDropCorrectionMixin(QtiAssociateInteraction) {
|
|
969
820
|
};
|
|
970
821
|
|
|
822
|
+
// ../qti-corrections/dist/mixins/choice-correction.mixin.js
|
|
823
|
+
var ChoiceCorrectionMixin = (superClass) => {
|
|
824
|
+
class ChoiceCorrectionMixinClass extends CandidateCorrectionMixin(superClass) {
|
|
825
|
+
toggleInternalCorrectResponse(show) {
|
|
826
|
+
super.toggleInternalCorrectResponse(show);
|
|
827
|
+
const correctResponse = this.correctResponse;
|
|
828
|
+
const correctResponses = correctResponse ? Array.isArray(correctResponse) ? correctResponse : [correctResponse] : [];
|
|
829
|
+
for (const choice of this._choiceElements) {
|
|
830
|
+
choice.internals.states.delete("correct-response");
|
|
831
|
+
choice.internals.states.delete("incorrect-response");
|
|
832
|
+
if (show && correctResponses.length > 0) {
|
|
833
|
+
choice.internals.states.add(correctResponses.includes(choice.identifier) ? "correct-response" : "incorrect-response");
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
toggleCandidateCorrection(show) {
|
|
838
|
+
super.toggleCandidateCorrection(show);
|
|
839
|
+
for (const choice of this._choiceElements) {
|
|
840
|
+
choice.candidateCorrection = null;
|
|
841
|
+
}
|
|
842
|
+
if (!show || !this.correctResponse) {
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
const correctResponses = Array.isArray(this.correctResponse) ? this.correctResponse : [this.correctResponse];
|
|
846
|
+
const candidateResponses = Array.isArray(this.response) ? this.response : this.response ? [this.response] : [];
|
|
847
|
+
for (const choice of this._choiceElements) {
|
|
848
|
+
if (!candidateResponses.includes(choice.identifier)) {
|
|
849
|
+
continue;
|
|
850
|
+
}
|
|
851
|
+
choice.candidateCorrection = correctResponses.includes(choice.identifier) ? "correct" : "incorrect";
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
return ChoiceCorrectionMixinClass;
|
|
856
|
+
};
|
|
857
|
+
|
|
971
858
|
// ../qti-corrections/dist/interactions/qti-choice-interaction-correction.js
|
|
972
859
|
var QtiChoiceInteractionCorrection = class extends ChoiceCorrectionMixin(QtiChoiceInteraction) {
|
|
973
860
|
};
|
|
@@ -1610,27 +1497,135 @@ var QtiTextEntryInteractionCorrection = class extends CandidateCorrectionMixin(Q
|
|
|
1610
1497
|
}
|
|
1611
1498
|
};
|
|
1612
1499
|
|
|
1500
|
+
// ../qti-corrections/dist/components/qti-assessment-item-correction.js
|
|
1501
|
+
var QtiAssessmentItemCorrection = class extends QtiAssessmentItem {
|
|
1502
|
+
showCorrectResponse(show) {
|
|
1503
|
+
for (const interaction of this.interactionElements) {
|
|
1504
|
+
interaction.toggleCorrectResponse?.(show);
|
|
1505
|
+
}
|
|
1506
|
+
this.updateControlState("item-show-correct-response", show);
|
|
1507
|
+
}
|
|
1508
|
+
showCandidateCorrection(show) {
|
|
1509
|
+
for (const interaction of this.interactionElements) {
|
|
1510
|
+
interaction.toggleCandidateCorrection?.(show);
|
|
1511
|
+
}
|
|
1512
|
+
this.updateControlState("item-show-candidate-correction", show);
|
|
1513
|
+
}
|
|
1514
|
+
afterResponseVariableUpdated() {
|
|
1515
|
+
this.showCandidateCorrection(false);
|
|
1516
|
+
}
|
|
1517
|
+
updateControlState(selector, shown) {
|
|
1518
|
+
let root = this.getRootNode();
|
|
1519
|
+
while (true) {
|
|
1520
|
+
root.querySelectorAll(selector).forEach((control) => control.shown = shown);
|
|
1521
|
+
if (!(root instanceof ShadowRoot))
|
|
1522
|
+
return;
|
|
1523
|
+
root = root.host.getRootNode();
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
};
|
|
1527
|
+
|
|
1528
|
+
// ../qti-corrections/dist/components/qti-item-correction.js
|
|
1529
|
+
var QtiItemCorrection = class extends QtiItem {
|
|
1530
|
+
#onShowCorrectResponse = (event) => {
|
|
1531
|
+
const show = event.detail;
|
|
1532
|
+
this.assessmentItem?.showCorrectResponse?.(show);
|
|
1533
|
+
this.updateControlState("item-show-correct-response", show);
|
|
1534
|
+
};
|
|
1535
|
+
#onShowCandidateCorrection = (event) => {
|
|
1536
|
+
const show = event.detail;
|
|
1537
|
+
this.assessmentItem?.showCandidateCorrection?.(show);
|
|
1538
|
+
this.updateControlState("item-show-candidate-correction", show);
|
|
1539
|
+
};
|
|
1540
|
+
#onSwitchCorrectResponseMode = (event) => {
|
|
1541
|
+
this.assessmentItem?.showCorrectResponse?.(false);
|
|
1542
|
+
this.configContext = {
|
|
1543
|
+
...this.configContext,
|
|
1544
|
+
correctResponseMode: event.detail
|
|
1545
|
+
};
|
|
1546
|
+
};
|
|
1547
|
+
constructor() {
|
|
1548
|
+
super();
|
|
1549
|
+
this.addEventListener("item-show-correct-response", this.#onShowCorrectResponse);
|
|
1550
|
+
this.addEventListener("item-show-candidate-correction", this.#onShowCandidateCorrection);
|
|
1551
|
+
this.addEventListener("item-switch-correct-response-mode", this.#onSwitchCorrectResponseMode);
|
|
1552
|
+
}
|
|
1553
|
+
updateControlState(selector, shown) {
|
|
1554
|
+
this.querySelectorAll(selector).forEach((control) => control.shown = shown);
|
|
1555
|
+
}
|
|
1556
|
+
disconnectedCallback() {
|
|
1557
|
+
this.removeEventListener("item-show-correct-response", this.#onShowCorrectResponse);
|
|
1558
|
+
this.removeEventListener("item-show-candidate-correction", this.#onShowCandidateCorrection);
|
|
1559
|
+
this.removeEventListener("item-switch-correct-response-mode", this.#onSwitchCorrectResponseMode);
|
|
1560
|
+
super.disconnectedCallback();
|
|
1561
|
+
}
|
|
1562
|
+
};
|
|
1563
|
+
|
|
1564
|
+
// ../qti-corrections/dist/components/test-correction-elements.js
|
|
1565
|
+
var TestNavigationCorrection = class extends TestNavigation {
|
|
1566
|
+
#onShowCorrectResponse = (event) => {
|
|
1567
|
+
this.activeAssessmentItem?.showCorrectResponse?.(event.detail);
|
|
1568
|
+
};
|
|
1569
|
+
#onShowCandidateCorrection = (event) => {
|
|
1570
|
+
this.activeAssessmentItem?.showCandidateCorrection?.(event.detail);
|
|
1571
|
+
};
|
|
1572
|
+
constructor() {
|
|
1573
|
+
super();
|
|
1574
|
+
this.addEventListener("test-show-correct-response", this.#onShowCorrectResponse);
|
|
1575
|
+
this.addEventListener("test-show-candidate-correction", this.#onShowCandidateCorrection);
|
|
1576
|
+
}
|
|
1577
|
+
disconnectedCallback() {
|
|
1578
|
+
this.removeEventListener("test-show-correct-response", this.#onShowCorrectResponse);
|
|
1579
|
+
this.removeEventListener("test-show-candidate-correction", this.#onShowCandidateCorrection);
|
|
1580
|
+
super.disconnectedCallback();
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* Reflect correctness back to the candidate after an ended attempt, for items
|
|
1584
|
+
* the assessment opted in via the standard `qti-item-session-control
|
|
1585
|
+
* show-solution` (QTI 3.0 ItemSessionControl.show-solution) — the player takes
|
|
1586
|
+
* no opinion of its own:
|
|
1587
|
+
* - candidate correction (a mark on the learner's selection) after every attempt;
|
|
1588
|
+
* - the correct response (a mark on the right answer) once the item is done —
|
|
1589
|
+
* the candidate reached the optimal outcome, or ran out of attempts.
|
|
1590
|
+
*/
|
|
1591
|
+
afterAttemptEnded(assessmentItem, computedItem, done) {
|
|
1592
|
+
if (!assessmentItem || !computedItem?.showSolution)
|
|
1593
|
+
return;
|
|
1594
|
+
const correctable = assessmentItem;
|
|
1595
|
+
correctable.showCandidateCorrection?.(true);
|
|
1596
|
+
correctable.showCorrectResponse?.(done);
|
|
1597
|
+
}
|
|
1598
|
+
};
|
|
1599
|
+
var QtiTestCorrection = class extends QtiTest {
|
|
1600
|
+
updateAssessmentItemView(assessmentItem, view) {
|
|
1601
|
+
assessmentItem.showCorrectResponse?.(view === "scorer");
|
|
1602
|
+
}
|
|
1603
|
+
};
|
|
1604
|
+
var TestCheckItemCorrection = class extends TestCheckItem {
|
|
1605
|
+
constructor() {
|
|
1606
|
+
super();
|
|
1607
|
+
this.addEventListener("click", () => {
|
|
1608
|
+
this.dispatchEvent(new CustomEvent("test-show-correct-response", { detail: true, bubbles: true }));
|
|
1609
|
+
});
|
|
1610
|
+
}
|
|
1611
|
+
};
|
|
1612
|
+
|
|
1613
1613
|
export {
|
|
1614
|
-
|
|
1615
|
-
|
|
1614
|
+
ItemCorrectResponseMode,
|
|
1615
|
+
ItemShowCandidateCorrection,
|
|
1616
|
+
ItemShowCorrectResponse,
|
|
1617
|
+
TestShowCorrectResponse,
|
|
1616
1618
|
correctionPart,
|
|
1617
|
-
CandidateCorrectionMixin,
|
|
1618
|
-
ChoiceCorrectionMixin,
|
|
1619
1619
|
QtiGapTextCorrection,
|
|
1620
1620
|
QtiHotspotChoiceCorrection,
|
|
1621
1621
|
QtiHottextCorrection,
|
|
1622
1622
|
QtiSimpleAssociableChoiceCorrection,
|
|
1623
1623
|
QtiSimpleChoiceCorrection,
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
QtiTestCorrection,
|
|
1628
|
-
TestCheckItemCorrection,
|
|
1629
|
-
ItemCorrectResponseMode,
|
|
1630
|
-
ItemShowCandidateCorrection,
|
|
1631
|
-
ItemShowCorrectResponse,
|
|
1632
|
-
TestShowCorrectResponse,
|
|
1624
|
+
Correctness,
|
|
1625
|
+
CorrectResponseMixin,
|
|
1626
|
+
CandidateCorrectionMixin,
|
|
1633
1627
|
QtiAssociateInteractionCorrection,
|
|
1628
|
+
ChoiceCorrectionMixin,
|
|
1634
1629
|
QtiChoiceInteractionCorrection,
|
|
1635
1630
|
QtiExtendedTextInteractionCorrection,
|
|
1636
1631
|
QtiGapMatchInteractionCorrection,
|
|
@@ -1645,6 +1640,11 @@ export {
|
|
|
1645
1640
|
QtiPortableCustomInteractionCorrection,
|
|
1646
1641
|
QtiSelectPointInteractionCorrection,
|
|
1647
1642
|
QtiSliderInteractionCorrection,
|
|
1648
|
-
QtiTextEntryInteractionCorrection
|
|
1643
|
+
QtiTextEntryInteractionCorrection,
|
|
1644
|
+
QtiAssessmentItemCorrection,
|
|
1645
|
+
QtiItemCorrection,
|
|
1646
|
+
TestNavigationCorrection,
|
|
1647
|
+
QtiTestCorrection,
|
|
1648
|
+
TestCheckItemCorrection
|
|
1649
1649
|
};
|
|
1650
|
-
//# sourceMappingURL=chunk-
|
|
1650
|
+
//# sourceMappingURL=chunk-5SU3MP6Y.js.map
|