@qti-components/elements 2.0.0-next.5 → 2.0.0-next.7
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/dist/components/qti-assessment-item/qti-assessment-item.d.ts +2 -2
- package/dist/components/qti-assessment-item/qti-assessment-item.js +10 -10
- package/dist/components/qti-assessment-item/qti-assessment-item.js.map +1 -1
- package/dist/components/qti-feedback-block/qti-feedback-block.d.ts +10 -0
- package/dist/components/qti-feedback-block/qti-feedback-block.js +15 -0
- package/dist/components/qti-feedback-block/qti-feedback-block.js.map +1 -1
- package/dist/components/qti-feedback-inline/qti-feedback-inline.d.ts +10 -0
- package/dist/components/qti-feedback-inline/qti-feedback-inline.js +15 -0
- package/dist/components/qti-feedback-inline/qti-feedback-inline.js.map +1 -1
- package/dist/components/qti-item-body/qti-item-body.d.ts +2 -1
- package/dist/components/qti-item-body/qti-item-body.js +3 -2
- package/dist/components/qti-item-body/qti-item-body.js.map +1 -1
- package/dist/components/qti-modal-feedback/qti-modal-feedback.d.ts +10 -0
- package/dist/components/qti-modal-feedback/qti-modal-feedback.js +15 -0
- package/dist/components/qti-modal-feedback/qti-modal-feedback.js.map +1 -1
- package/dist/components/qti-response-processing/qti-response-processing.d.ts +2 -2
- package/dist/components/qti-response-processing/qti-response-processing.js +3 -3
- package/dist/components/qti-response-processing/qti-response-processing.js.map +1 -1
- package/dist/components/qti-rubric-block/qti-rubric-block.js +1 -1
- package/dist/components/qti-rubric-block/qti-rubric-block.js.map +1 -1
- package/dist/internal/feedback-events.d.ts +10 -0
- package/dist/internal/feedback-events.js +17 -0
- package/dist/internal/feedback-events.js.map +1 -0
- package/dist/public-events.d.ts +29 -9
- package/dist/public-events.js +8 -10
- package/dist/public-events.js.map +1 -1
- package/package.json +3 -3
|
@@ -49,7 +49,7 @@ export declare class QtiAssessmentItem extends LitElement {
|
|
|
49
49
|
disconnectedCallback(): void;
|
|
50
50
|
/**
|
|
51
51
|
* Scores the attempt. The item does not score itself: its response processing does, like a
|
|
52
|
-
* backend, and sends the outcomes back in `
|
|
52
|
+
* backend, and sends the outcomes back in `qc-item-set-outcomes`, which the item applies in one
|
|
53
53
|
* update. The item keeps the attempt count (QTI info model §2.2.2: the delivery engine maintains
|
|
54
54
|
* numAttempts) and hands the new count to the run, whose rules may read it. Without response
|
|
55
55
|
* processing the item only counts the attempt. A run that throws still counts the attempt and applies
|
|
@@ -108,6 +108,6 @@ declare global {
|
|
|
108
108
|
declare module '../../public-events' {
|
|
109
109
|
interface PublicItemEventMap {
|
|
110
110
|
/** The item rendered: its interactions are in the DOM and its validity is known. */
|
|
111
|
-
'
|
|
111
|
+
'qc-item-rendered': CustomEvent<QtiAssessmentItem>;
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -256,7 +256,7 @@ export class QtiAssessmentItem extends LitElement {
|
|
|
256
256
|
// The verdict goes in first, so whoever hears the item connect reads it with the rest.
|
|
257
257
|
this.validate(false);
|
|
258
258
|
this.#beginFirstAttempt();
|
|
259
|
-
dispatchPublic(this, '
|
|
259
|
+
dispatchPublic(this, 'qc-item-rendered', this);
|
|
260
260
|
// Internal plumbing: the test and the item container listen for this name.
|
|
261
261
|
this.dispatchEvent(new CustomEvent('qti-assessment-item-connected', {
|
|
262
262
|
bubbles: true,
|
|
@@ -274,7 +274,7 @@ export class QtiAssessmentItem extends LitElement {
|
|
|
274
274
|
this.addEventListener('qti-register-variable', this.#handleRegisterVariable);
|
|
275
275
|
this.addEventListener('qti-register-interaction', this.#handleRegisterInteraction);
|
|
276
276
|
this.addEventListener('end-attempt', this.#handleEndAttempt);
|
|
277
|
-
this.addEventListener('
|
|
277
|
+
this.addEventListener('qc-item-set-outcomes', this.#handleSetOutcomes);
|
|
278
278
|
this.addEventListener('qti-set-template-value', this.#handleSetTemplateValue);
|
|
279
279
|
this.addEventListener('qti-set-correct-response', this.#handleSetCorrectResponse);
|
|
280
280
|
this.addEventListener('qti-interaction-response', this.#handleUpdateResponseVariable);
|
|
@@ -283,7 +283,7 @@ export class QtiAssessmentItem extends LitElement {
|
|
|
283
283
|
this.removeEventListener('qti-register-variable', this.#handleRegisterVariable);
|
|
284
284
|
this.removeEventListener('qti-register-interaction', this.#handleRegisterInteraction);
|
|
285
285
|
this.removeEventListener('end-attempt', this.#handleEndAttempt);
|
|
286
|
-
this.removeEventListener('
|
|
286
|
+
this.removeEventListener('qc-item-set-outcomes', this.#handleSetOutcomes);
|
|
287
287
|
this.removeEventListener('qti-set-template-value', this.#handleSetTemplateValue);
|
|
288
288
|
this.removeEventListener('qti-set-correct-response', this.#handleSetCorrectResponse);
|
|
289
289
|
this.removeEventListener('qti-interaction-response', this.#handleUpdateResponseVariable);
|
|
@@ -323,7 +323,7 @@ export class QtiAssessmentItem extends LitElement {
|
|
|
323
323
|
}
|
|
324
324
|
/**
|
|
325
325
|
* Scores the attempt. The item does not score itself: its response processing does, like a
|
|
326
|
-
* backend, and sends the outcomes back in `
|
|
326
|
+
* backend, and sends the outcomes back in `qc-item-set-outcomes`, which the item applies in one
|
|
327
327
|
* update. The item keeps the attempt count (QTI info model §2.2.2: the delivery engine maintains
|
|
328
328
|
* numAttempts) and hands the new count to the run, whose rules may read it. Without response
|
|
329
329
|
* processing the item only counts the attempt. A run that throws still counts the attempt and applies
|
|
@@ -351,7 +351,7 @@ export class QtiAssessmentItem extends LitElement {
|
|
|
351
351
|
}
|
|
352
352
|
return true;
|
|
353
353
|
}
|
|
354
|
-
dispatchPublic(this, '
|
|
354
|
+
dispatchPublic(this, 'qc-item-set-outcomes', {
|
|
355
355
|
outcomes: [{ identifier: 'numAttempts', value: String(numAttempts) }],
|
|
356
356
|
responseProcessed: true
|
|
357
357
|
});
|
|
@@ -417,7 +417,7 @@ export class QtiAssessmentItem extends LitElement {
|
|
|
417
417
|
variables: this._context.variables.map(v => (v.identifier !== identifier ? v : { ...v, value: value }))
|
|
418
418
|
};
|
|
419
419
|
this.afterResponseVariableUpdated();
|
|
420
|
-
dispatchPublic(this, '
|
|
420
|
+
dispatchPublic(this, 'qc-item-response-changed', {
|
|
421
421
|
item: this.identifier,
|
|
422
422
|
responseIdentifier: identifier,
|
|
423
423
|
response: Array.isArray(value) ? [...value] : value
|
|
@@ -514,8 +514,8 @@ export class QtiAssessmentItem extends LitElement {
|
|
|
514
514
|
this.#applyOutcomes([{ identifier, value }]);
|
|
515
515
|
}
|
|
516
516
|
/**
|
|
517
|
-
* Publishes the outcomes (and the validity) in one update, then a `
|
|
518
|
-
* outcome with its final value and one `
|
|
517
|
+
* Publishes the outcomes (and the validity) in one update, then a `qc-item-outcome-changed` per
|
|
518
|
+
* outcome with its final value and one `qc-item-outcomes-changed` with all of them.
|
|
519
519
|
* An identifier the item does not declare is skipped with a warning; a later entry for the same
|
|
520
520
|
* identifier wins.
|
|
521
521
|
*/
|
|
@@ -539,13 +539,13 @@ export class QtiAssessmentItem extends LitElement {
|
|
|
539
539
|
};
|
|
540
540
|
if (values.size > 0) {
|
|
541
541
|
for (const [outcomeIdentifier, value] of values) {
|
|
542
|
-
dispatchPublic(this, '
|
|
542
|
+
dispatchPublic(this, 'qc-item-outcome-changed', {
|
|
543
543
|
item: this.identifier,
|
|
544
544
|
outcomeIdentifier,
|
|
545
545
|
value: value
|
|
546
546
|
});
|
|
547
547
|
}
|
|
548
|
-
dispatchPublic(this, '
|
|
548
|
+
dispatchPublic(this, 'qc-item-outcomes-changed', {
|
|
549
549
|
item: this.identifier,
|
|
550
550
|
outcomes: [...values].map(([identifier, value]) => ({ identifier, value }))
|
|
551
551
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-assessment-item.js","sourceRoot":"","sources":["../../../src/components/qti-assessment-item/qti-assessment-item.ts"],"names":[],"mappings":"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","sourcesContent":["import { provide } from '@lit/context';\nimport { LitElement, html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { itemContext, itemContextVariables } from '@qti-components/base';\n\nimport { dispatchPublic } from '../../public-events';\n\nimport type { PropertyValues } from 'lit';\nimport type { QtiTemplateProcessing } from '../qti-template-processing/qti-template-processing.js';\nimport type { InteractionChangedDetails, OutcomeEntry, SetOutcomesDetails } from '../../internal/event-types.ts';\nimport type { ResponseInteraction } from '@qti-components/base';\nimport type { RegisteredInteraction } from '@qti-components/base';\nimport type { VariableDeclaration, VariableValue } from '@qti-components/base';\nimport type { OutcomeVariable, ResponseVariable, TemplateVariable } from '@qti-components/base';\nimport type QtiRegisterVariable from '../../internal/events/qti-register-variable.ts';\nimport type { ItemContext } from '@qti-components/base';\n\n/**\n * @summary The qti-assessment-item element contains all the other QTI 3 item structures.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.dltnnj87l0yj\n *\n * @dependency qti-feedback\n * @dependency qti-responseprocessing\n *\n * @event qti-item-context-updated - Emitted when through a user action the itemContext is updated,\n * typically on interaction with the interactions, or calling response processing.\n */\n\n/**\n * What the item needs of its response processing: start a run for an attempt. The result comes\n * back as an event.\n */\ninterface ResponseProcessor {\n processResponse(options: { numAttempts: number }): void;\n}\n\nexport class QtiAssessmentItem extends LitElement {\n #itemTitle: string | undefined;\n #templateProcessing: QtiTemplateProcessing | null = null;\n\n @property({ type: String }) identifier: string = '';\n @property({ type: String }) adaptive: 'true' | 'false' = 'false';\n /*\n * `attribute` spelled out: Lit derives `timedependent` from the property\n * name, while QTI writes `time-dependent`. Without it the attribute never\n * reached the property, so an item declaring `time-dependent=\"true\"` still\n * reported false to `test-navigation`, which reads this to build the computed\n * item context.\n */\n @property({ type: String, attribute: 'time-dependent' }) timeDependent: 'true' | 'false' | null = null;\n\n @property({ type: String })\n override get title(): string {\n return this.#itemTitle;\n }\n override set title(value: string) {\n this.#itemTitle = value;\n this.removeAttribute('title');\n this.setAttribute('data-title', value);\n }\n\n /**\n * Locks the item, for example once it is submitted. Published in the item context, which the\n * interactions inside follow, so the item keeps no list of them to set it on.\n */\n @property({ type: Boolean }) disabled: boolean;\n\n /**\n * Shows the item for reading only. Published in the item context, which the interactions inside\n * follow, so the item keeps no list of them to set it on.\n */\n @property({ type: Boolean }) readonly: boolean;\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n const readonlyChanged = changed.has('readonly') && (this.readonly ?? false) !== (this._context.readonly ?? false);\n const disabledChanged = changed.has('disabled') && (this.disabled ?? false) !== (this._context.disabled ?? false);\n if (readonlyChanged || disabledChanged) {\n this._context = {\n ...this._context,\n ...(readonlyChanged ? { readonly: !!this.readonly } : {}),\n ...(disabledChanged ? { disabled: !!this.disabled } : {})\n };\n }\n }\n\n @provide({ context: itemContext })\n private _context: ItemContext = {\n variables: itemContextVariables\n };\n\n /**\n * Sets the identifier for the assessment item reference if this item is in a test.\n *\n * @param identifier - The identifier for the assessment item reference.\n */\n public set assessmentItemRefId(identifier: string) {\n this._context = { ...this._context, identifier };\n }\n\n public get assessmentItemRefId(): string {\n return this._context.identifier;\n }\n\n /**\n * The item's whole context, declarations included, for reading. `variables` is the trimmed view\n * for hosts; the test needs the declarations too, and used to reach for the private field.\n */\n public get itemContext(): Readonly<ItemContext> {\n return this._context;\n }\n\n public get variables(): VariableValue<string | string[] | null>[] {\n return this._context.variables.map(v => ({\n identifier: v.identifier,\n value: v.value,\n type: v.type,\n // add externalscored, a fixed prop to the test, so the testcontext can read and decide how to score this item\n ...(v.type === 'outcome' && v.identifier === 'SCORE'\n ? { externalScored: (v as OutcomeVariable).externalScored }\n : {})\n }));\n }\n\n public set variables(value: VariableValue<string | string[] | null>[]) {\n if (!Array.isArray(value) || value.some(v => !('identifier' in v))) {\n console.warn('variables property should be an array of VariableDeclaration');\n return;\n }\n const previous = this._context.variables;\n // Recognised by their declaration, or by their own type: a template declaration registers after\n // its first render, so a test restoring on connect can get here before it has.\n const restoredTemplates = value.filter(\n v =>\n v.value !== null &&\n v.value !== undefined &&\n (v.type === 'template' ||\n previous.some(declared => declared.identifier === v.identifier && declared.type === 'template'))\n );\n restoredTemplates.forEach(v =>\n this.#restoredTemplateValues.set(v.identifier, v.value as Readonly<string | string[]>)\n );\n const templatesChanged = restoredTemplates.some(\n v =>\n JSON.stringify(previous.find(declared => declared.identifier === v.identifier)?.value) !==\n JSON.stringify(v.value)\n );\n\n this._context = {\n ...this._context,\n variables: this._context.variables.map(variable => {\n const matchingValue = value.find(v => v.identifier === variable.identifier);\n if (matchingValue) {\n return {\n ...variable,\n ...matchingValue,\n interpolationTable: (variable as OutcomeVariable).interpolationTable,\n matchTable: (variable as OutcomeVariable).matchTable\n };\n }\n return variable;\n })\n };\n\n // Restored after the first processing run: correct responses still follow the values it drew.\n if (this.#templatesProcessed && templatesChanged) {\n this.#runTemplateProcessing();\n }\n\n // The interactions take the answers over from the context, some of them a moment from now, and\n // a different answer can mean a different verdict. Look once they have.\n void this.updateComplete.then(() => this.#revalidate());\n if (this.isConnected) this.#beginFirstAttempt();\n }\n\n public get state(): ItemContext['state'] {\n return this._context.state;\n }\n\n public set state(value: ItemContext['state']) {\n this._context = {\n ...this._context,\n state: value ? { ...value } : undefined\n };\n }\n\n #initialContext: Readonly<ItemContext> = { ...this._context, variables: this._context.variables };\n /**\n * Template values handed in through `variables` — drawn in an earlier visit or session. Template\n * processing keeps them instead of drawing again, so the candidate sees the question they\n * answered, and still runs, so correct responses are derived from them.\n */\n #restoredTemplateValues = new Map<string, Readonly<string | string[]>>();\n #templatesProcessed = false;\n /** Registered candidate-input interactions. Correction packages may extend their presentation behavior. */\n protected interactionElements: RegisteredInteraction[] = [];\n\n /** @deprecated use variables property instead */\n set responses(myResponses: ResponseInteraction[]) {\n if (myResponses) {\n for (const response of myResponses) {\n const responseVariable = this.getResponse(response.responseIdentifier);\n if (responseVariable) {\n this.updateResponseVariable(response.responseIdentifier, response.response);\n }\n\n const interaction: RegisteredInteraction | undefined = this.interactionElements.find(\n i => i.getAttribute('response-identifier') === response.responseIdentifier\n );\n if (interaction) {\n interaction.response = response.response;\n }\n }\n }\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n\n override connectedCallback(): void {\n this.#attachEventListeners();\n super.connectedCallback();\n this.updateComplete.then(() => {\n // The verdict goes in first, so whoever hears the item connect reads it with the rest.\n this.validate(false);\n this.#beginFirstAttempt();\n dispatchPublic(this, 'cito-item-rendered', this);\n // Internal plumbing: the test and the item container listen for this name.\n this.dispatchEvent(\n new CustomEvent<QtiAssessmentItem>('qti-assessment-item-connected', {\n bubbles: true,\n composed: true,\n detail: this\n })\n );\n this.#processTemplates();\n });\n }\n\n override disconnectedCallback(): void {\n this.#removeEventListeners();\n super.disconnectedCallback();\n }\n\n #attachEventListeners() {\n this.addEventListener('qti-register-variable', this.#handleRegisterVariable);\n this.addEventListener('qti-register-interaction', this.#handleRegisterInteraction);\n this.addEventListener('end-attempt', this.#handleEndAttempt);\n this.addEventListener('cito-item-set-outcomes', this.#handleSetOutcomes);\n this.addEventListener('qti-set-template-value', this.#handleSetTemplateValue);\n this.addEventListener('qti-set-correct-response', this.#handleSetCorrectResponse);\n this.addEventListener('qti-interaction-response', this.#handleUpdateResponseVariable);\n }\n\n #removeEventListeners() {\n this.removeEventListener('qti-register-variable', this.#handleRegisterVariable);\n this.removeEventListener('qti-register-interaction', this.#handleRegisterInteraction);\n this.removeEventListener('end-attempt', this.#handleEndAttempt);\n this.removeEventListener('cito-item-set-outcomes', this.#handleSetOutcomes);\n this.removeEventListener('qti-set-template-value', this.#handleSetTemplateValue);\n this.removeEventListener('qti-set-correct-response', this.#handleSetCorrectResponse);\n this.removeEventListener('qti-interaction-response', this.#handleUpdateResponseVariable);\n }\n\n #handleRegisterVariable = (e: QtiRegisterVariable) => {\n e.stopImmediatePropagation();\n const { variable } = e.detail;\n const restored = variable.type === 'template' ? this.#restoredTemplateValues.get(variable.identifier) : undefined;\n const registered = restored !== undefined ? { ...variable, value: restored } : variable;\n this._context = { ...this._context, variables: [...this._context.variables, registered] };\n this.#initialContext = this._context;\n e.stopPropagation();\n };\n\n #handleRegisterInteraction = (e: CustomEvent<{ interaction: string; interactionElement: RegisteredInteraction }>) => {\n e.stopImmediatePropagation();\n this.interactionElements.push(e.detail.interactionElement);\n };\n\n #handleEndAttempt = (e: CustomEvent<{ responseIdentifier: string; countAttempt: boolean }>) => {\n e.stopImmediatePropagation();\n const { responseIdentifier, countAttempt } = e.detail;\n this.validate();\n this.updateResponseVariable(responseIdentifier, 'true');\n this.#processResponse(countAttempt, true, responseIdentifier);\n };\n\n /**\n * Applies the outcomes of a processing run, ours or a backend's, in one update, with the\n * interactions' validity.\n *\n * completionStatus is response processing's to set (QTI info model §2.2.2). When an attempt of a\n * non-adaptive item ends and processing left it `unknown`, the item marks it `completed`: the\n * attempt is done. TAO does the same, and the 1EdTech results-reporting reference results expect\n * it. An adaptive item is completed only by its own processing.\n */\n #handleSetOutcomes = (e: CustomEvent<SetOutcomesDetails>) => {\n e.stopImmediatePropagation();\n const { outcomes = [], responseProcessed = false } = e.detail ?? {};\n const completion: OutcomeEntry[] = [];\n if (responseProcessed && this.adaptive === 'false') {\n const sent = outcomes.find(o => o.identifier === 'completionStatus')?.value;\n if ((sent ?? this.getVariable('completionStatus')?.value) === 'unknown') {\n completion.push({ identifier: 'completionStatus', value: 'completed' });\n }\n }\n this.#applyOutcomes([...outcomes, ...completion], this.#checkValidity(false));\n\n if (responseProcessed) {\n // `responseProcessed` marks this as the end of an attempt (vs. a plain\n // selection, which fires the same event without the flag). Lets listeners\n // react only when an attempt actually ends.\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext; responseProcessed: boolean }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context, responseProcessed: true }\n })\n );\n }\n };\n\n #handleSetTemplateValue = (e: CustomEvent<{ templateIdentifier: string; value: string | string[] | null }>) => {\n e.stopImmediatePropagation();\n const { templateIdentifier, value } = e.detail;\n if (!this.#restoredTemplateValues.has(templateIdentifier)) {\n this.updateTemplateVariable(templateIdentifier, value ?? undefined);\n }\n e.stopPropagation();\n };\n\n #handleSetCorrectResponse = (e: CustomEvent<{ responseIdentifier: string; value: string | string[] | null }>) => {\n e.stopImmediatePropagation();\n const { responseIdentifier, value } = e.detail;\n this.updateCorrectResponse(responseIdentifier, value ?? undefined);\n e.stopPropagation();\n };\n\n #handleUpdateResponseVariable = (e: CustomEvent<ResponseInteraction>) => {\n e.stopImmediatePropagation();\n\n const { responseIdentifier, response, state } = e.detail;\n this.updateResponseVariable(responseIdentifier, response);\n if (state !== undefined) {\n this._context = {\n ...this._context,\n state: {\n ...(this._context.state || {}),\n [responseIdentifier]: state\n }\n };\n }\n\n // The interaction has updated its own validity by now; publish the verdict with the answer.\n this.validate(false);\n\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n };\n\n async #processTemplates(): Promise<void> {\n const templateDeclarations = Array.from(this.querySelectorAll<LitElement>('qti-template-declaration'));\n if (templateDeclarations.length > 0) {\n await Promise.all(templateDeclarations.map(declaration => declaration.updateComplete));\n await Promise.resolve();\n }\n\n this.#templateProcessing = this.querySelector<QtiTemplateProcessing>('qti-template-processing');\n this.#templatesProcessed = true;\n // Run template processing before first presentation\n this.#runTemplateProcessing();\n }\n\n #runTemplateProcessing(): void {\n if (!this.#templateProcessing) return;\n this.#templateProcessing.process();\n this.#initialContext = { ...this._context, variables: this._context.variables };\n }\n\n /**\n * Scores the attempt. The item does not score itself: its response processing does, like a\n * backend, and sends the outcomes back in `cito-item-set-outcomes`, which the item applies in one\n * update. The item keeps the attempt count (QTI info model §2.2.2: the delivery engine maintains\n * numAttempts) and hands the new count to the run, whose rules may read it. Without response\n * processing the item only counts the attempt. A run that throws still counts the attempt and applies\n * no outcomes.\n *\n * @returns whether the item has response processing.\n */\n public processResponse(countNumAttempts = true, reportValidityAfterScoring = true): boolean {\n return this.#processResponse(countNumAttempts, reportValidityAfterScoring);\n }\n\n #processResponse(countNumAttempts: boolean, reportValidity: boolean, endedBy?: string): boolean {\n this.#checkValidity(reportValidity);\n this.#resetOtherEndAttempts(endedBy);\n\n const numAttempts = +this.getVariable('numAttempts')?.value + (countNumAttempts ? 1 : 0);\n const processor = this.querySelector<HTMLElement & Partial<ResponseProcessor>>('qti-response-processing');\n if (typeof processor?.processResponse === 'function') {\n try {\n processor.processResponse({ numAttempts });\n } catch (error) {\n // The attempt started, so it counts (QTI info model §2.2.2), as in TAO and Amp-up; the\n // outcomes of a run that failed are not applied.\n this.#applyOutcomes([{ identifier: 'numAttempts', value: String(numAttempts) }]);\n throw error;\n }\n return true;\n }\n dispatchPublic(this, 'cito-item-set-outcomes', {\n outcomes: [{ identifier: 'numAttempts', value: String(numAttempts) }],\n responseProcessed: true\n });\n return false;\n }\n\n /**\n * QTI info model §2.4.5: when an attempt ends any other way than through an end-attempt\n * interaction, that interaction's response is `false`.\n */\n #resetOtherEndAttempts(endedBy: string | undefined): void {\n const others = Array.from(this.querySelectorAll('qti-end-attempt-interaction'), el =>\n el.getAttribute('response-identifier')\n ).filter(id => id && id !== endedBy);\n if (others.length === 0) return;\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v => (others.includes(v.identifier) ? { ...v, value: 'false' } : v))\n };\n }\n\n public resetResponses() {\n this._context = this.#initialContext;\n if (this.isConnected) this.#beginFirstAttempt();\n }\n\n /**\n * QTI info model §2.2.2: completionStatus is `not_attempted` until the first attempt starts, then\n * `unknown`. The attempt starts when the candidate gets the item, so an item on screen is never\n * `not_attempted` — also not after a reset or a restore that says so.\n */\n #beginFirstAttempt(): void {\n if (this.getVariable('completionStatus')?.value !== 'not_attempted') return;\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v =>\n v.identifier === 'completionStatus' ? { ...v, value: 'unknown' } : v\n )\n };\n }\n\n protected getResponse(identifier: string): Readonly<ResponseVariable> {\n return this.getVariable(identifier) as ResponseVariable;\n }\n\n public getOutcome(identifier: string): Readonly<OutcomeVariable> {\n return this.getVariable(identifier) as OutcomeVariable;\n }\n\n protected getVariable(identifier: string): Readonly<VariableDeclaration<string | string[] | null>> {\n return this._context.variables.find(v => v.identifier === identifier) || null;\n }\n\n /** Extension point for presentation packages reacting to a candidate response change. */\n protected afterResponseVariableUpdated(): void {}\n\n // saving privates here: ------------------------------------------------------------------------------\n\n /**\n * Updates the response variable with the specified identifier to the given value.\n *\n * @protected\n *\n * This method is intended for internal use within the class and subclasses.\n * It should not be called externally by third parties.\n *\n * @param identifier - The identifier of the response variable to update.\n * @param value - The new value for the response variable.\n */\n public updateResponseVariable(identifier: string, value: string | string[] | undefined) {\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v => (v.identifier !== identifier ? v : { ...v, value: value }))\n };\n\n this.afterResponseVariableUpdated();\n\n dispatchPublic(this, 'cito-item-response-changed', {\n item: this.identifier,\n responseIdentifier: identifier,\n response: Array.isArray(value) ? [...value] : value\n });\n\n // A different answer can mean a different verdict.\n this.validate(false);\n }\n\n /**\n * Updates the template variable with the specified identifier to the given value.\n */\n public updateTemplateVariable(identifier: string, value: string | string[] | undefined) {\n const templateVariable = this._context.variables.find(v => v.identifier === identifier && v.type === 'template') as\n | TemplateVariable\n | undefined;\n\n if (!templateVariable) {\n console.warn(`Can not set qti-template-identifier: ${identifier}, it is not available`);\n return;\n }\n\n const normalizedValue =\n templateVariable.cardinality === 'single'\n ? Array.isArray(value)\n ? value[0]\n : (value ?? null)\n : value === undefined || value === null\n ? null\n : Array.isArray(value)\n ? value\n : [value];\n\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v =>\n v.identifier !== identifier\n ? v\n : {\n ...v,\n value: normalizedValue\n }\n )\n };\n\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n\n /**\n * Updates the correct response for the specified response variable.\n */\n public updateCorrectResponse(identifier: string, value: string | string[] | undefined) {\n const responseVariable = this.getResponse(identifier);\n\n if (!responseVariable) {\n console.warn(`Can not set correct response for identifier: ${identifier}, it is not available`);\n return;\n }\n\n const normalizedValue =\n responseVariable.cardinality === 'single'\n ? Array.isArray(value)\n ? value[0]\n : (value ?? null)\n : value === undefined || value === null\n ? null\n : Array.isArray(value)\n ? value\n : [value];\n\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v =>\n v.identifier !== identifier\n ? v\n : {\n ...v,\n correctResponse: normalizedValue\n }\n )\n };\n\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n\n public setOutcomeVariable(identifier: string, value: string | string[] | undefined) {\n this.updateOutcomeVariable(identifier, value);\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n\n /**\n * Updates the outcome variable with the specified identifier to the given value.\n *\n * @protected\n *\n * This method is intended for internal use within the class and subclasses.\n * It should not be called externally by third parties.\n *\n * @param identifier - The identifier of the response variable to update.\n * @param value - The new value for the response variable.\n */\n public updateOutcomeVariable(identifier: string, value: string | string[] | undefined) {\n this.#applyOutcomes([{ identifier, value }]);\n }\n\n /**\n * Publishes the outcomes (and the validity) in one update, then a `cito-item-outcome-changed` per\n * outcome with its final value and one `cito-item-outcomes-changed` with all of them.\n * An identifier the item does not declare is skipped with a warning; a later entry for the same\n * identifier wins.\n */\n #applyOutcomes(outcomes: readonly OutcomeEntry[], valid?: boolean) {\n const values = new Map<string, OutcomeEntry['value']>();\n for (const { identifier, value } of outcomes) {\n const variable = this.getVariable(identifier);\n if (!variable) {\n console.warn(`Can not set qti-outcome-identifier: ${identifier}, it is not available`);\n continue;\n }\n values.set(identifier, variable.cardinality === 'single' ? value : Array.isArray(value) ? value : [value]);\n }\n const validChanged = valid !== undefined && valid !== this._context.valid;\n if (values.size === 0 && !validChanged) return;\n\n this._context = {\n ...this._context,\n ...(validChanged ? { valid } : {}),\n variables: this._context.variables.map(v =>\n values.has(v.identifier) ? { ...v, value: values.get(v.identifier) as string | string[] | null } : v\n )\n };\n\n if (values.size > 0) {\n for (const [outcomeIdentifier, value] of values) {\n dispatchPublic(this, 'cito-item-outcome-changed', {\n item: this.identifier,\n outcomeIdentifier,\n value: value as string | string[]\n });\n }\n dispatchPublic(this, 'cito-item-outcomes-changed', {\n item: this.identifier,\n outcomes: [...values].map(([identifier, value]) => ({ identifier, value }))\n });\n }\n }\n\n public validate(reportValidity = true): boolean {\n const isValid = this.#checkValidity(reportValidity);\n this.#publishValidity(isValid);\n return isValid;\n }\n\n #checkValidity(reportValidity: boolean): boolean {\n const isValid = this.interactionElements.every(interactionElement => interactionElement.validate());\n if (reportValidity) {\n this.reportValidity();\n }\n return isValid;\n }\n\n /** Puts the verdict in the item context, where the test and anything else can read it. */\n #publishValidity(valid: boolean): void {\n if (this._context.valid !== valid) {\n this._context = { ...this._context, valid };\n }\n }\n\n /**\n * Checks again after something the interactions' validity depends on changed without them saying\n * so (an answer handed in through `variables`), and tells the test if the verdict moved.\n */\n #revalidate(): void {\n const before = this._context.valid;\n this.validate(false);\n if (this._context.valid !== before) {\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n }\n\n public reportValidity() {\n for (const interactionElement of this.interactionElements) {\n interactionElement.reportValidity();\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-assessment-item': QtiAssessmentItem;\n }\n}\n\ndeclare module '../../public-events' {\n interface PublicItemEventMap {\n /** The item rendered: its interactions are in the DOM and its validity is known. */\n 'cito-item-rendered': CustomEvent<QtiAssessmentItem>;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"qti-assessment-item.js","sourceRoot":"","sources":["../../../src/components/qti-assessment-item/qti-assessment-item.ts"],"names":[],"mappings":"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","sourcesContent":["import { provide } from '@lit/context';\nimport { LitElement, html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { itemContext, itemContextVariables } from '@qti-components/base';\n\nimport { dispatchPublic } from '../../public-events';\n\nimport type { PropertyValues } from 'lit';\nimport type { QtiTemplateProcessing } from '../qti-template-processing/qti-template-processing.js';\nimport type { InteractionChangedDetails, OutcomeEntry, SetOutcomesDetails } from '../../internal/event-types.ts';\nimport type { ResponseInteraction } from '@qti-components/base';\nimport type { RegisteredInteraction } from '@qti-components/base';\nimport type { VariableDeclaration, VariableValue } from '@qti-components/base';\nimport type { OutcomeVariable, ResponseVariable, TemplateVariable } from '@qti-components/base';\nimport type QtiRegisterVariable from '../../internal/events/qti-register-variable.ts';\nimport type { ItemContext } from '@qti-components/base';\n\n/**\n * @summary The qti-assessment-item element contains all the other QTI 3 item structures.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.dltnnj87l0yj\n *\n * @dependency qti-feedback\n * @dependency qti-responseprocessing\n *\n * @event qti-item-context-updated - Emitted when through a user action the itemContext is updated,\n * typically on interaction with the interactions, or calling response processing.\n */\n\n/**\n * What the item needs of its response processing: start a run for an attempt. The result comes\n * back as an event.\n */\ninterface ResponseProcessor {\n processResponse(options: { numAttempts: number }): void;\n}\n\nexport class QtiAssessmentItem extends LitElement {\n #itemTitle: string | undefined;\n #templateProcessing: QtiTemplateProcessing | null = null;\n\n @property({ type: String }) identifier: string = '';\n @property({ type: String }) adaptive: 'true' | 'false' = 'false';\n /*\n * `attribute` spelled out: Lit derives `timedependent` from the property\n * name, while QTI writes `time-dependent`. Without it the attribute never\n * reached the property, so an item declaring `time-dependent=\"true\"` still\n * reported false to `test-navigation`, which reads this to build the computed\n * item context.\n */\n @property({ type: String, attribute: 'time-dependent' }) timeDependent: 'true' | 'false' | null = null;\n\n @property({ type: String })\n override get title(): string {\n return this.#itemTitle;\n }\n override set title(value: string) {\n this.#itemTitle = value;\n this.removeAttribute('title');\n this.setAttribute('data-title', value);\n }\n\n /**\n * Locks the item, for example once it is submitted. Published in the item context, which the\n * interactions inside follow, so the item keeps no list of them to set it on.\n */\n @property({ type: Boolean }) disabled: boolean;\n\n /**\n * Shows the item for reading only. Published in the item context, which the interactions inside\n * follow, so the item keeps no list of them to set it on.\n */\n @property({ type: Boolean }) readonly: boolean;\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n const readonlyChanged = changed.has('readonly') && (this.readonly ?? false) !== (this._context.readonly ?? false);\n const disabledChanged = changed.has('disabled') && (this.disabled ?? false) !== (this._context.disabled ?? false);\n if (readonlyChanged || disabledChanged) {\n this._context = {\n ...this._context,\n ...(readonlyChanged ? { readonly: !!this.readonly } : {}),\n ...(disabledChanged ? { disabled: !!this.disabled } : {})\n };\n }\n }\n\n @provide({ context: itemContext })\n private _context: ItemContext = {\n variables: itemContextVariables\n };\n\n /**\n * Sets the identifier for the assessment item reference if this item is in a test.\n *\n * @param identifier - The identifier for the assessment item reference.\n */\n public set assessmentItemRefId(identifier: string) {\n this._context = { ...this._context, identifier };\n }\n\n public get assessmentItemRefId(): string {\n return this._context.identifier;\n }\n\n /**\n * The item's whole context, declarations included, for reading. `variables` is the trimmed view\n * for hosts; the test needs the declarations too, and used to reach for the private field.\n */\n public get itemContext(): Readonly<ItemContext> {\n return this._context;\n }\n\n public get variables(): VariableValue<string | string[] | null>[] {\n return this._context.variables.map(v => ({\n identifier: v.identifier,\n value: v.value,\n type: v.type,\n // add externalscored, a fixed prop to the test, so the testcontext can read and decide how to score this item\n ...(v.type === 'outcome' && v.identifier === 'SCORE'\n ? { externalScored: (v as OutcomeVariable).externalScored }\n : {})\n }));\n }\n\n public set variables(value: VariableValue<string | string[] | null>[]) {\n if (!Array.isArray(value) || value.some(v => !('identifier' in v))) {\n console.warn('variables property should be an array of VariableDeclaration');\n return;\n }\n const previous = this._context.variables;\n // Recognised by their declaration, or by their own type: a template declaration registers after\n // its first render, so a test restoring on connect can get here before it has.\n const restoredTemplates = value.filter(\n v =>\n v.value !== null &&\n v.value !== undefined &&\n (v.type === 'template' ||\n previous.some(declared => declared.identifier === v.identifier && declared.type === 'template'))\n );\n restoredTemplates.forEach(v =>\n this.#restoredTemplateValues.set(v.identifier, v.value as Readonly<string | string[]>)\n );\n const templatesChanged = restoredTemplates.some(\n v =>\n JSON.stringify(previous.find(declared => declared.identifier === v.identifier)?.value) !==\n JSON.stringify(v.value)\n );\n\n this._context = {\n ...this._context,\n variables: this._context.variables.map(variable => {\n const matchingValue = value.find(v => v.identifier === variable.identifier);\n if (matchingValue) {\n return {\n ...variable,\n ...matchingValue,\n interpolationTable: (variable as OutcomeVariable).interpolationTable,\n matchTable: (variable as OutcomeVariable).matchTable\n };\n }\n return variable;\n })\n };\n\n // Restored after the first processing run: correct responses still follow the values it drew.\n if (this.#templatesProcessed && templatesChanged) {\n this.#runTemplateProcessing();\n }\n\n // The interactions take the answers over from the context, some of them a moment from now, and\n // a different answer can mean a different verdict. Look once they have.\n void this.updateComplete.then(() => this.#revalidate());\n if (this.isConnected) this.#beginFirstAttempt();\n }\n\n public get state(): ItemContext['state'] {\n return this._context.state;\n }\n\n public set state(value: ItemContext['state']) {\n this._context = {\n ...this._context,\n state: value ? { ...value } : undefined\n };\n }\n\n #initialContext: Readonly<ItemContext> = { ...this._context, variables: this._context.variables };\n /**\n * Template values handed in through `variables` — drawn in an earlier visit or session. Template\n * processing keeps them instead of drawing again, so the candidate sees the question they\n * answered, and still runs, so correct responses are derived from them.\n */\n #restoredTemplateValues = new Map<string, Readonly<string | string[]>>();\n #templatesProcessed = false;\n /** Registered candidate-input interactions. Correction packages may extend their presentation behavior. */\n protected interactionElements: RegisteredInteraction[] = [];\n\n /** @deprecated use variables property instead */\n set responses(myResponses: ResponseInteraction[]) {\n if (myResponses) {\n for (const response of myResponses) {\n const responseVariable = this.getResponse(response.responseIdentifier);\n if (responseVariable) {\n this.updateResponseVariable(response.responseIdentifier, response.response);\n }\n\n const interaction: RegisteredInteraction | undefined = this.interactionElements.find(\n i => i.getAttribute('response-identifier') === response.responseIdentifier\n );\n if (interaction) {\n interaction.response = response.response;\n }\n }\n }\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n\n override connectedCallback(): void {\n this.#attachEventListeners();\n super.connectedCallback();\n this.updateComplete.then(() => {\n // The verdict goes in first, so whoever hears the item connect reads it with the rest.\n this.validate(false);\n this.#beginFirstAttempt();\n dispatchPublic(this, 'qc-item-rendered', this);\n // Internal plumbing: the test and the item container listen for this name.\n this.dispatchEvent(\n new CustomEvent<QtiAssessmentItem>('qti-assessment-item-connected', {\n bubbles: true,\n composed: true,\n detail: this\n })\n );\n this.#processTemplates();\n });\n }\n\n override disconnectedCallback(): void {\n this.#removeEventListeners();\n super.disconnectedCallback();\n }\n\n #attachEventListeners() {\n this.addEventListener('qti-register-variable', this.#handleRegisterVariable);\n this.addEventListener('qti-register-interaction', this.#handleRegisterInteraction);\n this.addEventListener('end-attempt', this.#handleEndAttempt);\n this.addEventListener('qc-item-set-outcomes', this.#handleSetOutcomes);\n this.addEventListener('qti-set-template-value', this.#handleSetTemplateValue);\n this.addEventListener('qti-set-correct-response', this.#handleSetCorrectResponse);\n this.addEventListener('qti-interaction-response', this.#handleUpdateResponseVariable);\n }\n\n #removeEventListeners() {\n this.removeEventListener('qti-register-variable', this.#handleRegisterVariable);\n this.removeEventListener('qti-register-interaction', this.#handleRegisterInteraction);\n this.removeEventListener('end-attempt', this.#handleEndAttempt);\n this.removeEventListener('qc-item-set-outcomes', this.#handleSetOutcomes);\n this.removeEventListener('qti-set-template-value', this.#handleSetTemplateValue);\n this.removeEventListener('qti-set-correct-response', this.#handleSetCorrectResponse);\n this.removeEventListener('qti-interaction-response', this.#handleUpdateResponseVariable);\n }\n\n #handleRegisterVariable = (e: QtiRegisterVariable) => {\n e.stopImmediatePropagation();\n const { variable } = e.detail;\n const restored = variable.type === 'template' ? this.#restoredTemplateValues.get(variable.identifier) : undefined;\n const registered = restored !== undefined ? { ...variable, value: restored } : variable;\n this._context = { ...this._context, variables: [...this._context.variables, registered] };\n this.#initialContext = this._context;\n e.stopPropagation();\n };\n\n #handleRegisterInteraction = (e: CustomEvent<{ interaction: string; interactionElement: RegisteredInteraction }>) => {\n e.stopImmediatePropagation();\n this.interactionElements.push(e.detail.interactionElement);\n };\n\n #handleEndAttempt = (e: CustomEvent<{ responseIdentifier: string; countAttempt: boolean }>) => {\n e.stopImmediatePropagation();\n const { responseIdentifier, countAttempt } = e.detail;\n this.validate();\n this.updateResponseVariable(responseIdentifier, 'true');\n this.#processResponse(countAttempt, true, responseIdentifier);\n };\n\n /**\n * Applies the outcomes of a processing run, ours or a backend's, in one update, with the\n * interactions' validity.\n *\n * completionStatus is response processing's to set (QTI info model §2.2.2). When an attempt of a\n * non-adaptive item ends and processing left it `unknown`, the item marks it `completed`: the\n * attempt is done. TAO does the same, and the 1EdTech results-reporting reference results expect\n * it. An adaptive item is completed only by its own processing.\n */\n #handleSetOutcomes = (e: CustomEvent<SetOutcomesDetails>) => {\n e.stopImmediatePropagation();\n const { outcomes = [], responseProcessed = false } = e.detail ?? {};\n const completion: OutcomeEntry[] = [];\n if (responseProcessed && this.adaptive === 'false') {\n const sent = outcomes.find(o => o.identifier === 'completionStatus')?.value;\n if ((sent ?? this.getVariable('completionStatus')?.value) === 'unknown') {\n completion.push({ identifier: 'completionStatus', value: 'completed' });\n }\n }\n this.#applyOutcomes([...outcomes, ...completion], this.#checkValidity(false));\n\n if (responseProcessed) {\n // `responseProcessed` marks this as the end of an attempt (vs. a plain\n // selection, which fires the same event without the flag). Lets listeners\n // react only when an attempt actually ends.\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext; responseProcessed: boolean }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context, responseProcessed: true }\n })\n );\n }\n };\n\n #handleSetTemplateValue = (e: CustomEvent<{ templateIdentifier: string; value: string | string[] | null }>) => {\n e.stopImmediatePropagation();\n const { templateIdentifier, value } = e.detail;\n if (!this.#restoredTemplateValues.has(templateIdentifier)) {\n this.updateTemplateVariable(templateIdentifier, value ?? undefined);\n }\n e.stopPropagation();\n };\n\n #handleSetCorrectResponse = (e: CustomEvent<{ responseIdentifier: string; value: string | string[] | null }>) => {\n e.stopImmediatePropagation();\n const { responseIdentifier, value } = e.detail;\n this.updateCorrectResponse(responseIdentifier, value ?? undefined);\n e.stopPropagation();\n };\n\n #handleUpdateResponseVariable = (e: CustomEvent<ResponseInteraction>) => {\n e.stopImmediatePropagation();\n\n const { responseIdentifier, response, state } = e.detail;\n this.updateResponseVariable(responseIdentifier, response);\n if (state !== undefined) {\n this._context = {\n ...this._context,\n state: {\n ...(this._context.state || {}),\n [responseIdentifier]: state\n }\n };\n }\n\n // The interaction has updated its own validity by now; publish the verdict with the answer.\n this.validate(false);\n\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n };\n\n async #processTemplates(): Promise<void> {\n const templateDeclarations = Array.from(this.querySelectorAll<LitElement>('qti-template-declaration'));\n if (templateDeclarations.length > 0) {\n await Promise.all(templateDeclarations.map(declaration => declaration.updateComplete));\n await Promise.resolve();\n }\n\n this.#templateProcessing = this.querySelector<QtiTemplateProcessing>('qti-template-processing');\n this.#templatesProcessed = true;\n // Run template processing before first presentation\n this.#runTemplateProcessing();\n }\n\n #runTemplateProcessing(): void {\n if (!this.#templateProcessing) return;\n this.#templateProcessing.process();\n this.#initialContext = { ...this._context, variables: this._context.variables };\n }\n\n /**\n * Scores the attempt. The item does not score itself: its response processing does, like a\n * backend, and sends the outcomes back in `qc-item-set-outcomes`, which the item applies in one\n * update. The item keeps the attempt count (QTI info model §2.2.2: the delivery engine maintains\n * numAttempts) and hands the new count to the run, whose rules may read it. Without response\n * processing the item only counts the attempt. A run that throws still counts the attempt and applies\n * no outcomes.\n *\n * @returns whether the item has response processing.\n */\n public processResponse(countNumAttempts = true, reportValidityAfterScoring = true): boolean {\n return this.#processResponse(countNumAttempts, reportValidityAfterScoring);\n }\n\n #processResponse(countNumAttempts: boolean, reportValidity: boolean, endedBy?: string): boolean {\n this.#checkValidity(reportValidity);\n this.#resetOtherEndAttempts(endedBy);\n\n const numAttempts = +this.getVariable('numAttempts')?.value + (countNumAttempts ? 1 : 0);\n const processor = this.querySelector<HTMLElement & Partial<ResponseProcessor>>('qti-response-processing');\n if (typeof processor?.processResponse === 'function') {\n try {\n processor.processResponse({ numAttempts });\n } catch (error) {\n // The attempt started, so it counts (QTI info model §2.2.2), as in TAO and Amp-up; the\n // outcomes of a run that failed are not applied.\n this.#applyOutcomes([{ identifier: 'numAttempts', value: String(numAttempts) }]);\n throw error;\n }\n return true;\n }\n dispatchPublic(this, 'qc-item-set-outcomes', {\n outcomes: [{ identifier: 'numAttempts', value: String(numAttempts) }],\n responseProcessed: true\n });\n return false;\n }\n\n /**\n * QTI info model §2.4.5: when an attempt ends any other way than through an end-attempt\n * interaction, that interaction's response is `false`.\n */\n #resetOtherEndAttempts(endedBy: string | undefined): void {\n const others = Array.from(this.querySelectorAll('qti-end-attempt-interaction'), el =>\n el.getAttribute('response-identifier')\n ).filter(id => id && id !== endedBy);\n if (others.length === 0) return;\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v => (others.includes(v.identifier) ? { ...v, value: 'false' } : v))\n };\n }\n\n public resetResponses() {\n this._context = this.#initialContext;\n if (this.isConnected) this.#beginFirstAttempt();\n }\n\n /**\n * QTI info model §2.2.2: completionStatus is `not_attempted` until the first attempt starts, then\n * `unknown`. The attempt starts when the candidate gets the item, so an item on screen is never\n * `not_attempted` — also not after a reset or a restore that says so.\n */\n #beginFirstAttempt(): void {\n if (this.getVariable('completionStatus')?.value !== 'not_attempted') return;\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v =>\n v.identifier === 'completionStatus' ? { ...v, value: 'unknown' } : v\n )\n };\n }\n\n protected getResponse(identifier: string): Readonly<ResponseVariable> {\n return this.getVariable(identifier) as ResponseVariable;\n }\n\n public getOutcome(identifier: string): Readonly<OutcomeVariable> {\n return this.getVariable(identifier) as OutcomeVariable;\n }\n\n protected getVariable(identifier: string): Readonly<VariableDeclaration<string | string[] | null>> {\n return this._context.variables.find(v => v.identifier === identifier) || null;\n }\n\n /** Extension point for presentation packages reacting to a candidate response change. */\n protected afterResponseVariableUpdated(): void {}\n\n // saving privates here: ------------------------------------------------------------------------------\n\n /**\n * Updates the response variable with the specified identifier to the given value.\n *\n * @protected\n *\n * This method is intended for internal use within the class and subclasses.\n * It should not be called externally by third parties.\n *\n * @param identifier - The identifier of the response variable to update.\n * @param value - The new value for the response variable.\n */\n public updateResponseVariable(identifier: string, value: string | string[] | undefined) {\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v => (v.identifier !== identifier ? v : { ...v, value: value }))\n };\n\n this.afterResponseVariableUpdated();\n\n dispatchPublic(this, 'qc-item-response-changed', {\n item: this.identifier,\n responseIdentifier: identifier,\n response: Array.isArray(value) ? [...value] : value\n });\n\n // A different answer can mean a different verdict.\n this.validate(false);\n }\n\n /**\n * Updates the template variable with the specified identifier to the given value.\n */\n public updateTemplateVariable(identifier: string, value: string | string[] | undefined) {\n const templateVariable = this._context.variables.find(v => v.identifier === identifier && v.type === 'template') as\n | TemplateVariable\n | undefined;\n\n if (!templateVariable) {\n console.warn(`Can not set qti-template-identifier: ${identifier}, it is not available`);\n return;\n }\n\n const normalizedValue =\n templateVariable.cardinality === 'single'\n ? Array.isArray(value)\n ? value[0]\n : (value ?? null)\n : value === undefined || value === null\n ? null\n : Array.isArray(value)\n ? value\n : [value];\n\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v =>\n v.identifier !== identifier\n ? v\n : {\n ...v,\n value: normalizedValue\n }\n )\n };\n\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n\n /**\n * Updates the correct response for the specified response variable.\n */\n public updateCorrectResponse(identifier: string, value: string | string[] | undefined) {\n const responseVariable = this.getResponse(identifier);\n\n if (!responseVariable) {\n console.warn(`Can not set correct response for identifier: ${identifier}, it is not available`);\n return;\n }\n\n const normalizedValue =\n responseVariable.cardinality === 'single'\n ? Array.isArray(value)\n ? value[0]\n : (value ?? null)\n : value === undefined || value === null\n ? null\n : Array.isArray(value)\n ? value\n : [value];\n\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v =>\n v.identifier !== identifier\n ? v\n : {\n ...v,\n correctResponse: normalizedValue\n }\n )\n };\n\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n\n public setOutcomeVariable(identifier: string, value: string | string[] | undefined) {\n this.updateOutcomeVariable(identifier, value);\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n\n /**\n * Updates the outcome variable with the specified identifier to the given value.\n *\n * @protected\n *\n * This method is intended for internal use within the class and subclasses.\n * It should not be called externally by third parties.\n *\n * @param identifier - The identifier of the response variable to update.\n * @param value - The new value for the response variable.\n */\n public updateOutcomeVariable(identifier: string, value: string | string[] | undefined) {\n this.#applyOutcomes([{ identifier, value }]);\n }\n\n /**\n * Publishes the outcomes (and the validity) in one update, then a `qc-item-outcome-changed` per\n * outcome with its final value and one `qc-item-outcomes-changed` with all of them.\n * An identifier the item does not declare is skipped with a warning; a later entry for the same\n * identifier wins.\n */\n #applyOutcomes(outcomes: readonly OutcomeEntry[], valid?: boolean) {\n const values = new Map<string, OutcomeEntry['value']>();\n for (const { identifier, value } of outcomes) {\n const variable = this.getVariable(identifier);\n if (!variable) {\n console.warn(`Can not set qti-outcome-identifier: ${identifier}, it is not available`);\n continue;\n }\n values.set(identifier, variable.cardinality === 'single' ? value : Array.isArray(value) ? value : [value]);\n }\n const validChanged = valid !== undefined && valid !== this._context.valid;\n if (values.size === 0 && !validChanged) return;\n\n this._context = {\n ...this._context,\n ...(validChanged ? { valid } : {}),\n variables: this._context.variables.map(v =>\n values.has(v.identifier) ? { ...v, value: values.get(v.identifier) as string | string[] | null } : v\n )\n };\n\n if (values.size > 0) {\n for (const [outcomeIdentifier, value] of values) {\n dispatchPublic(this, 'qc-item-outcome-changed', {\n item: this.identifier,\n outcomeIdentifier,\n value: value as string | string[]\n });\n }\n dispatchPublic(this, 'qc-item-outcomes-changed', {\n item: this.identifier,\n outcomes: [...values].map(([identifier, value]) => ({ identifier, value }))\n });\n }\n }\n\n public validate(reportValidity = true): boolean {\n const isValid = this.#checkValidity(reportValidity);\n this.#publishValidity(isValid);\n return isValid;\n }\n\n #checkValidity(reportValidity: boolean): boolean {\n const isValid = this.interactionElements.every(interactionElement => interactionElement.validate());\n if (reportValidity) {\n this.reportValidity();\n }\n return isValid;\n }\n\n /** Puts the verdict in the item context, where the test and anything else can read it. */\n #publishValidity(valid: boolean): void {\n if (this._context.valid !== valid) {\n this._context = { ...this._context, valid };\n }\n }\n\n /**\n * Checks again after something the interactions' validity depends on changed without them saying\n * so (an answer handed in through `variables`), and tells the test if the verdict moved.\n */\n #revalidate(): void {\n const before = this._context.valid;\n this.validate(false);\n if (this._context.valid !== before) {\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n }\n\n public reportValidity() {\n for (const interactionElement of this.interactionElements) {\n interactionElement.reportValidity();\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-assessment-item': QtiAssessmentItem;\n }\n}\n\ndeclare module '../../public-events' {\n interface PublicItemEventMap {\n /** The item rendered: its interactions are in the DOM and its validity is known. */\n 'qc-item-rendered': CustomEvent<QtiAssessmentItem>;\n }\n}\n"]}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import { QtiFeedback } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* Block feedback: shown or hidden by the outcome it is bound to.
|
|
4
|
+
*
|
|
5
|
+
* @slot - The feedback content.
|
|
6
|
+
*
|
|
7
|
+
* @csspart feedback - The feedback box.
|
|
8
|
+
*/
|
|
2
9
|
export declare class QtiFeedbackBlock extends QtiFeedback {
|
|
3
10
|
static styles: import("lit").CSSResult;
|
|
4
11
|
render(): import("lit").TemplateResult<1>;
|
|
12
|
+
/** `qc-feedback-show`: a listener that calls `preventDefault()` keeps this hidden and shows it itself. */
|
|
13
|
+
protected feedbackShowing(): boolean;
|
|
14
|
+
protected feedbackHiding(): boolean;
|
|
5
15
|
connectedCallback(): void;
|
|
6
16
|
}
|
|
7
17
|
declare global {
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { css, html } from 'lit';
|
|
2
2
|
import { QtiFeedback } from '@qti-components/base';
|
|
3
|
+
import { dispatchFeedback } from '../../internal/feedback-events';
|
|
4
|
+
/**
|
|
5
|
+
* Block feedback: shown or hidden by the outcome it is bound to.
|
|
6
|
+
*
|
|
7
|
+
* @slot - The feedback content.
|
|
8
|
+
*
|
|
9
|
+
* @csspart feedback - The feedback box.
|
|
10
|
+
*/
|
|
3
11
|
export class QtiFeedbackBlock extends QtiFeedback {
|
|
4
12
|
static { this.styles = css `
|
|
5
13
|
:host {
|
|
@@ -15,6 +23,13 @@ export class QtiFeedbackBlock extends QtiFeedback {
|
|
|
15
23
|
render() {
|
|
16
24
|
return html ` <slot part="feedback" class="feedback ${this.showStatus}"></slot> `;
|
|
17
25
|
}
|
|
26
|
+
/** `qc-feedback-show`: a listener that calls `preventDefault()` keeps this hidden and shows it itself. */
|
|
27
|
+
feedbackShowing() {
|
|
28
|
+
return dispatchFeedback(this, 'qc-feedback-show', 'block', this.identifier);
|
|
29
|
+
}
|
|
30
|
+
feedbackHiding() {
|
|
31
|
+
return dispatchFeedback(this, 'qc-feedback-hide', 'block', this.identifier);
|
|
32
|
+
}
|
|
18
33
|
connectedCallback() {
|
|
19
34
|
super.connectedCallback();
|
|
20
35
|
this.checkShowFeedback(this.outcomeIdentifier);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-feedback-block.js","sourceRoot":"","sources":["../../../src/components/qti-feedback-block/qti-feedback-block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,MAAM,OAAO,gBAAiB,SAAQ,WAAW;aAC/B,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;GAU3B,CAAC;IAEO,MAAM;QACb,OAAO,IAAI,CAAA,0CAA0C,IAAI,CAAC,UAAU,YAAY,CAAC;IACnF,CAAC;IAEe,iBAAiB;QAC/B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjD,CAAC","sourcesContent":["import { css, html } from 'lit';\n\nimport { QtiFeedback } from '@qti-components/base';\n\nexport class QtiFeedbackBlock extends QtiFeedback {\n static override styles = css`\n :host {\n display: block;\n }\n .on {\n display: block;\n }\n .off {\n display: none;\n }\n `;\n\n override render() {\n return html` <slot part=\"feedback\" class=\"feedback ${this.showStatus}\"></slot> `;\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.checkShowFeedback(this.outcomeIdentifier);\n }\n}\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-feedback-block': QtiFeedbackBlock;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"qti-feedback-block.js","sourceRoot":"","sources":["../../../src/components/qti-feedback-block/qti-feedback-block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,OAAO,gBAAiB,SAAQ,WAAW;aAC/B,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;GAU3B,CAAC;IAEO,MAAM;QACb,OAAO,IAAI,CAAA,0CAA0C,IAAI,CAAC,UAAU,YAAY,CAAC;IACnF,CAAC;IAED,0GAA0G;IACvF,eAAe;QAChC,OAAO,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9E,CAAC;IAEkB,cAAc;QAC/B,OAAO,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9E,CAAC;IAEe,iBAAiB;QAC/B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjD,CAAC","sourcesContent":["import { css, html } from 'lit';\n\nimport { QtiFeedback } from '@qti-components/base';\n\nimport { dispatchFeedback } from '../../internal/feedback-events';\n\n/**\n * Block feedback: shown or hidden by the outcome it is bound to.\n *\n * @slot - The feedback content.\n *\n * @csspart feedback - The feedback box.\n */\nexport class QtiFeedbackBlock extends QtiFeedback {\n static override styles = css`\n :host {\n display: block;\n }\n .on {\n display: block;\n }\n .off {\n display: none;\n }\n `;\n\n override render() {\n return html` <slot part=\"feedback\" class=\"feedback ${this.showStatus}\"></slot> `;\n }\n\n /** `qc-feedback-show`: a listener that calls `preventDefault()` keeps this hidden and shows it itself. */\n protected override feedbackShowing(): boolean {\n return dispatchFeedback(this, 'qc-feedback-show', 'block', this.identifier);\n }\n\n protected override feedbackHiding(): boolean {\n return dispatchFeedback(this, 'qc-feedback-hide', 'block', this.identifier);\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.checkShowFeedback(this.outcomeIdentifier);\n }\n}\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-feedback-block': QtiFeedbackBlock;\n }\n}\n"]}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import { QtiFeedback } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* Inline feedback: shown or hidden by the outcome it is bound to.
|
|
4
|
+
*
|
|
5
|
+
* @slot - The feedback content.
|
|
6
|
+
*
|
|
7
|
+
* @csspart feedback - The feedback box.
|
|
8
|
+
*/
|
|
2
9
|
export declare class QtiFeedbackInline extends QtiFeedback {
|
|
3
10
|
static styles: import("lit").CSSResult;
|
|
4
11
|
render: () => import("lit").TemplateResult<1>;
|
|
12
|
+
/** `qc-feedback-show`: a listener that calls `preventDefault()` keeps this hidden and shows it itself. */
|
|
13
|
+
protected feedbackShowing(): boolean;
|
|
14
|
+
protected feedbackHiding(): boolean;
|
|
5
15
|
connectedCallback(): void;
|
|
6
16
|
}
|
|
7
17
|
declare global {
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { css, html } from 'lit';
|
|
2
2
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
3
3
|
import { QtiFeedback } from '@qti-components/base';
|
|
4
|
+
import { dispatchFeedback } from '../../internal/feedback-events';
|
|
5
|
+
/**
|
|
6
|
+
* Inline feedback: shown or hidden by the outcome it is bound to.
|
|
7
|
+
*
|
|
8
|
+
* @slot - The feedback content.
|
|
9
|
+
*
|
|
10
|
+
* @csspart feedback - The feedback box.
|
|
11
|
+
*/
|
|
4
12
|
export class QtiFeedbackInline extends QtiFeedback {
|
|
5
13
|
constructor() {
|
|
6
14
|
super(...arguments);
|
|
@@ -14,6 +22,13 @@ export class QtiFeedbackInline extends QtiFeedback {
|
|
|
14
22
|
display: none;
|
|
15
23
|
}
|
|
16
24
|
`; }
|
|
25
|
+
/** `qc-feedback-show`: a listener that calls `preventDefault()` keeps this hidden and shows it itself. */
|
|
26
|
+
feedbackShowing() {
|
|
27
|
+
return dispatchFeedback(this, 'qc-feedback-show', 'inline', this.identifier);
|
|
28
|
+
}
|
|
29
|
+
feedbackHiding() {
|
|
30
|
+
return dispatchFeedback(this, 'qc-feedback-hide', 'inline', this.identifier);
|
|
31
|
+
}
|
|
17
32
|
connectedCallback() {
|
|
18
33
|
super.connectedCallback();
|
|
19
34
|
this.checkShowFeedback(this.outcomeIdentifier);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-feedback-inline.js","sourceRoot":"","sources":["../../../src/components/qti-feedback-inline/qti-feedback-inline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,MAAM,OAAO,iBAAkB,SAAQ,WAAW;IAAlD;;QAUW,WAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAA,iCAAiC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"qti-feedback-inline.js","sourceRoot":"","sources":["../../../src/components/qti-feedback-inline/qti-feedback-inline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,OAAO,iBAAkB,SAAQ,WAAW;IAAlD;;QAUW,WAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAA,iCAAiC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;IAetG,CAAC;aAxBiB,WAAM,GAAG,GAAG,CAAA;;;;;;;GAO3B,AAPqB,CAOpB;IAIF,0GAA0G;IACvF,eAAe;QAChC,OAAO,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/E,CAAC;IAEkB,cAAc;QAC/B,OAAO,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/E,CAAC;IAEe,iBAAiB;QAC/B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjD,CAAC","sourcesContent":["import { css, html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { QtiFeedback } from '@qti-components/base';\n\nimport { dispatchFeedback } from '../../internal/feedback-events';\n\n/**\n * Inline feedback: shown or hidden by the outcome it is bound to.\n *\n * @slot - The feedback content.\n *\n * @csspart feedback - The feedback box.\n */\nexport class QtiFeedbackInline extends QtiFeedback {\n static override styles = css`\n .on {\n display: inline-block;\n }\n .off {\n display: none;\n }\n `;\n\n override render = () => html` <slot part=\"feedback\" class=\"${ifDefined(this.showStatus)}\"></slot> `;\n\n /** `qc-feedback-show`: a listener that calls `preventDefault()` keeps this hidden and shows it itself. */\n protected override feedbackShowing(): boolean {\n return dispatchFeedback(this, 'qc-feedback-show', 'inline', this.identifier);\n }\n\n protected override feedbackHiding(): boolean {\n return dispatchFeedback(this, 'qc-feedback-hide', 'inline', this.identifier);\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.checkShowFeedback(this.outcomeIdentifier);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-feedback-inline': QtiFeedbackInline;\n }\n}\n"]}
|
|
@@ -8,7 +8,8 @@ import type { CSSResultGroup } from 'lit';
|
|
|
8
8
|
*
|
|
9
9
|
* @slot - item body content.
|
|
10
10
|
* @slot qti-rubric-block - the qti rubric block is placed above the item
|
|
11
|
-
*
|
|
11
|
+
*
|
|
12
|
+
* @csspart rubrics - The rubric-block slot (was `qti-rubric-blocks`).
|
|
12
13
|
*/
|
|
13
14
|
export declare class QtiItemBody extends LitElement {
|
|
14
15
|
static styles: CSSResultGroup;
|
|
@@ -8,12 +8,13 @@ import styles from './qti-item-body.styles';
|
|
|
8
8
|
*
|
|
9
9
|
* @slot - item body content.
|
|
10
10
|
* @slot qti-rubric-block - the qti rubric block is placed above the item
|
|
11
|
-
*
|
|
11
|
+
*
|
|
12
|
+
* @csspart rubrics - The rubric-block slot (was `qti-rubric-blocks`).
|
|
12
13
|
*/
|
|
13
14
|
export class QtiItemBody extends LitElement {
|
|
14
15
|
static { this.styles = styles; }
|
|
15
16
|
render() {
|
|
16
|
-
return html `<slot part="qti-rubric-blocks" name="qti-rubric-block"></slot><slot></slot>`;
|
|
17
|
+
return html `<slot part="rubrics qti-rubric-blocks" name="qti-rubric-block"></slot><slot></slot>`;
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
//# sourceMappingURL=qti-item-body.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-item-body.js","sourceRoot":"","sources":["../../../src/components/qti-item-body/qti-item-body.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEvC,OAAO,MAAM,MAAM,wBAAwB,CAAC;AAI5C
|
|
1
|
+
{"version":3,"file":"qti-item-body.js","sourceRoot":"","sources":["../../../src/components/qti-item-body/qti-item-body.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEvC,OAAO,MAAM,MAAM,wBAAwB,CAAC;AAI5C;;;;;;;;;;GAUG;AAEH,MAAM,OAAO,WAAY,SAAQ,UAAU;aACzB,WAAM,GAAmB,MAAM,CAAC;IAEvC,MAAM;QACb,OAAO,IAAI,CAAA,qFAAqF,CAAC;IACnG,CAAC","sourcesContent":["import { html, LitElement } from 'lit';\n\nimport styles from './qti-item-body.styles';\n\nimport type { CSSResultGroup } from 'lit';\n\n/**\n * @summary The qti-item-body node contains the text, graphics, media objects and interactions that describe the item's content and information about how it is structured.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.sphpo6lu6zqi\n * @status stable\n * @since 4.0\n *\n * @slot - item body content.\n * @slot qti-rubric-block - the qti rubric block is placed above the item\n *\n * @csspart rubrics - The rubric-block slot (was `qti-rubric-blocks`).\n */\n\nexport class QtiItemBody extends LitElement {\n static override styles: CSSResultGroup = styles;\n\n override render() {\n return html`<slot part=\"rubrics qti-rubric-blocks\" name=\"qti-rubric-block\"></slot><slot></slot>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-item-body': QtiItemBody;\n }\n}\n"]}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { QtiFeedback } from '@qti-components/base';
|
|
2
|
+
/**
|
|
3
|
+
* Modal feedback: a dialog opened by the outcome it is bound to.
|
|
4
|
+
*
|
|
5
|
+
* @slot - The feedback content.
|
|
6
|
+
*
|
|
7
|
+
* @csspart feedback - The feedback box (the dialog).
|
|
8
|
+
*/
|
|
2
9
|
export declare class QtiModalFeedback extends QtiFeedback {
|
|
3
10
|
static styles: import("lit").CSSResult;
|
|
4
11
|
render(): import("lit").TemplateResult<1>;
|
|
5
12
|
openFeedback(): void;
|
|
6
13
|
closeFeedback(): void;
|
|
14
|
+
/** `qc-feedback-show`: a listener that calls `preventDefault()` keeps this hidden and shows it itself. */
|
|
15
|
+
protected feedbackShowing(): boolean;
|
|
16
|
+
protected feedbackHiding(): boolean;
|
|
7
17
|
connectedCallback(): void;
|
|
8
18
|
protected updated(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
9
19
|
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { css, html } from 'lit';
|
|
2
2
|
import { QtiFeedback } from '@qti-components/base';
|
|
3
|
+
import { dispatchFeedback } from '../../internal/feedback-events';
|
|
4
|
+
/**
|
|
5
|
+
* Modal feedback: a dialog opened by the outcome it is bound to.
|
|
6
|
+
*
|
|
7
|
+
* @slot - The feedback content.
|
|
8
|
+
*
|
|
9
|
+
* @csspart feedback - The feedback box (the dialog).
|
|
10
|
+
*/
|
|
3
11
|
export class QtiModalFeedback extends QtiFeedback {
|
|
4
12
|
static { this.styles = css `
|
|
5
13
|
.cito-dialog {
|
|
@@ -63,6 +71,13 @@ export class QtiModalFeedback extends QtiFeedback {
|
|
|
63
71
|
this.showStatus = 'off';
|
|
64
72
|
}
|
|
65
73
|
}
|
|
74
|
+
/** `qc-feedback-show`: a listener that calls `preventDefault()` keeps this hidden and shows it itself. */
|
|
75
|
+
feedbackShowing() {
|
|
76
|
+
return dispatchFeedback(this, 'qc-feedback-show', 'modal', this.identifier);
|
|
77
|
+
}
|
|
78
|
+
feedbackHiding() {
|
|
79
|
+
return dispatchFeedback(this, 'qc-feedback-hide', 'modal', this.identifier);
|
|
80
|
+
}
|
|
66
81
|
connectedCallback() {
|
|
67
82
|
super.connectedCallback();
|
|
68
83
|
if (this.showStatus === 'on') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-modal-feedback.js","sourceRoot":"","sources":["../../../src/components/qti-modal-feedback/qti-modal-feedback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,MAAM,OAAO,gBAAiB,SAAQ,WAAW;aAC/B,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsC3B,CAAC;IAEO,MAAM;QACb,OAAO,IAAI,CAAA;2DAC4C,IAAI,CAAC,UAAU,KAAK,IAAI;;;wDAG3B,IAAI,CAAC,aAAa;;;KAGrE,CAAC;IACJ,CAAC;IAED,YAAY;QACV,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,QAAQ,CAA6B,CAAC;QACpF,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC3B,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED,aAAa;QACX,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,QAAQ,CAA6B,CAAC;QACpF,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IAEe,iBAAiB;QAC/B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAEkB,OAAO,CAAC,iBAAyD;QAClF,IAAI,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACxC,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC","sourcesContent":["import { css, html } from 'lit';\n\nimport { QtiFeedback } from '@qti-components/base';\n\nexport class QtiModalFeedback extends QtiFeedback {\n static override styles = css`\n .cito-dialog {\n background: var(--qti-bg);\n border: var(--qti-border-thickness) var(--qti-border-style) var(--qti-border-color);\n border-radius: var(--qti-border-radius);\n padding: var(--qti-padding-box);\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1000;\n width: auto;\n max-width: 90%;\n }\n\n .button {\n border-radius: var(--qti-border-radius);\n padding: var(--qti-padding-box);\n background-color: var(--qti-bg-active);\n border: var(--qti-border-active);\n cursor: pointer;\n position: relative;\n display: inline-block;\n }\n\n /* Inlined from --qti-disabled-bg / --qti-disabled-color, which this button was the only reader\n of anywhere in the repo. They were named as a global disabled vocabulary but no interaction\n ever used them: the theme's disabled treatment is cursor only (see the note in qti-mixins.css). */\n .button:disabled {\n background-color: transparent;\n color: var(--qti-fg);\n cursor: not-allowed;\n }\n\n .button:focus {\n outline: var(--qti-focus-border-width) solid var(--qti-focus-color);\n }\n `;\n\n override render() {\n return html`\n <dialog class=\"cito-dialog\" part=\"feedback\" ?open=\"${this.showStatus === 'on'}\">\n <slot></slot>\n <div style=\"margin-top: var(--qti-gap); text-align: center;\">\n <button class=\"button close-button\" @click=\"${this.closeFeedback}\">Close</button>\n </div>\n </dialog>\n `;\n }\n\n openFeedback() {\n const dialog = this.shadowRoot?.querySelector('dialog') as HTMLDialogElement | null;\n if (dialog && !dialog.open) {\n dialog.showModal();\n }\n }\n\n closeFeedback() {\n const dialog = this.shadowRoot?.querySelector('dialog') as HTMLDialogElement | null;\n if (dialog && dialog.open) {\n dialog.close();\n this.showStatus = 'off';\n }\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n if (this.showStatus === 'on') {\n this.openFeedback();\n }\n }\n\n protected override updated(changedProperties: Map<string | number | symbol, unknown>): void {\n if (changedProperties.has('showStatus')) {\n if (this.showStatus === 'on') {\n this.openFeedback();\n } else {\n this.closeFeedback();\n }\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-modal-feedback': QtiModalFeedback;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"qti-modal-feedback.js","sourceRoot":"","sources":["../../../src/components/qti-modal-feedback/qti-modal-feedback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,OAAO,gBAAiB,SAAQ,WAAW;aAC/B,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsC3B,CAAC;IAEO,MAAM;QACb,OAAO,IAAI,CAAA;2DAC4C,IAAI,CAAC,UAAU,KAAK,IAAI;;;wDAG3B,IAAI,CAAC,aAAa;;;KAGrE,CAAC;IACJ,CAAC;IAED,YAAY;QACV,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,QAAQ,CAA6B,CAAC;QACpF,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC3B,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED,aAAa;QACX,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,QAAQ,CAA6B,CAAC;QACpF,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,0GAA0G;IACvF,eAAe;QAChC,OAAO,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9E,CAAC;IAEkB,cAAc;QAC/B,OAAO,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9E,CAAC;IAEe,iBAAiB;QAC/B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAEkB,OAAO,CAAC,iBAAyD;QAClF,IAAI,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACxC,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC","sourcesContent":["import { css, html } from 'lit';\n\nimport { QtiFeedback } from '@qti-components/base';\n\nimport { dispatchFeedback } from '../../internal/feedback-events';\n\n/**\n * Modal feedback: a dialog opened by the outcome it is bound to.\n *\n * @slot - The feedback content.\n *\n * @csspart feedback - The feedback box (the dialog).\n */\nexport class QtiModalFeedback extends QtiFeedback {\n static override styles = css`\n .cito-dialog {\n background: var(--qti-bg);\n border: var(--qti-border-thickness) var(--qti-border-style) var(--qti-border-color);\n border-radius: var(--qti-border-radius);\n padding: var(--qti-padding-box);\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1000;\n width: auto;\n max-width: 90%;\n }\n\n .button {\n border-radius: var(--qti-border-radius);\n padding: var(--qti-padding-box);\n background-color: var(--qti-bg-active);\n border: var(--qti-border-active);\n cursor: pointer;\n position: relative;\n display: inline-block;\n }\n\n /* Inlined from --qti-disabled-bg / --qti-disabled-color, which this button was the only reader\n of anywhere in the repo. They were named as a global disabled vocabulary but no interaction\n ever used them: the theme's disabled treatment is cursor only (see the note in qti-mixins.css). */\n .button:disabled {\n background-color: transparent;\n color: var(--qti-fg);\n cursor: not-allowed;\n }\n\n .button:focus {\n outline: var(--qti-focus-border-width) solid var(--qti-focus-color);\n }\n `;\n\n override render() {\n return html`\n <dialog class=\"cito-dialog\" part=\"feedback\" ?open=\"${this.showStatus === 'on'}\">\n <slot></slot>\n <div style=\"margin-top: var(--qti-gap); text-align: center;\">\n <button class=\"button close-button\" @click=\"${this.closeFeedback}\">Close</button>\n </div>\n </dialog>\n `;\n }\n\n openFeedback() {\n const dialog = this.shadowRoot?.querySelector('dialog') as HTMLDialogElement | null;\n if (dialog && !dialog.open) {\n dialog.showModal();\n }\n }\n\n closeFeedback() {\n const dialog = this.shadowRoot?.querySelector('dialog') as HTMLDialogElement | null;\n if (dialog && dialog.open) {\n dialog.close();\n this.showStatus = 'off';\n }\n }\n\n /** `qc-feedback-show`: a listener that calls `preventDefault()` keeps this hidden and shows it itself. */\n protected override feedbackShowing(): boolean {\n return dispatchFeedback(this, 'qc-feedback-show', 'modal', this.identifier);\n }\n\n protected override feedbackHiding(): boolean {\n return dispatchFeedback(this, 'qc-feedback-hide', 'modal', this.identifier);\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n if (this.showStatus === 'on') {\n this.openFeedback();\n }\n }\n\n protected override updated(changedProperties: Map<string | number | symbol, unknown>): void {\n if (changedProperties.has('showStatus')) {\n if (this.showStatus === 'on') {\n this.openFeedback();\n } else {\n this.closeFeedback();\n }\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-modal-feedback': QtiModalFeedback;\n }\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import { LitElement } from 'lit';
|
|
|
2
2
|
import type { PropertyValueMap } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* Response processing as the item's own backend: it reads the item context, runs its rules once and
|
|
5
|
-
* sends the outcomes and the attempt count back in one `
|
|
5
|
+
* sends the outcomes and the attempt count back in one `qc-item-set-outcomes`. The item applies
|
|
6
6
|
* them; a host that scores elsewhere sends the same event instead.
|
|
7
7
|
*/
|
|
8
8
|
export declare class QtiResponseProcessing extends LitElement {
|
|
@@ -13,7 +13,7 @@ export declare class QtiResponseProcessing extends LitElement {
|
|
|
13
13
|
/**
|
|
14
14
|
* Scores the attempt on the copy: sets `numAttempts` to the count the item hands over, resets a
|
|
15
15
|
* non-adaptive item's outcomes to their defaults (QTI info model §2.5), runs the rules and sends
|
|
16
|
-
* every outcome and `numAttempts` in one `
|
|
16
|
+
* every outcome and `numAttempts` in one `qc-item-set-outcomes`. The item applies them and publishes, which gives this element a
|
|
17
17
|
* fresh copy. A rule that throws ends the run and the error propagates; nothing is sent, and the
|
|
18
18
|
* run's writes stay in the copy until the item's next update.
|
|
19
19
|
*/
|
|
@@ -11,7 +11,7 @@ const responseProcessingTemplates = {
|
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
13
|
* Response processing as the item's own backend: it reads the item context, runs its rules once and
|
|
14
|
-
* sends the outcomes and the attempt count back in one `
|
|
14
|
+
* sends the outcomes and the attempt count back in one `qc-item-set-outcomes`. The item applies
|
|
15
15
|
* them; a host that scores elsewhere sends the same event instead.
|
|
16
16
|
*/
|
|
17
17
|
export class QtiResponseProcessing extends LitElement {
|
|
@@ -60,7 +60,7 @@ export class QtiResponseProcessing extends LitElement {
|
|
|
60
60
|
/**
|
|
61
61
|
* Scores the attempt on the copy: sets `numAttempts` to the count the item hands over, resets a
|
|
62
62
|
* non-adaptive item's outcomes to their defaults (QTI info model §2.5), runs the rules and sends
|
|
63
|
-
* every outcome and `numAttempts` in one `
|
|
63
|
+
* every outcome and `numAttempts` in one `qc-item-set-outcomes`. The item applies them and publishes, which gives this element a
|
|
64
64
|
* fresh copy. A rule that throws ends the run and the error propagates; nothing is sent, and the
|
|
65
65
|
* run's writes stay in the copy until the item's next update.
|
|
66
66
|
*/
|
|
@@ -78,7 +78,7 @@ export class QtiResponseProcessing extends LitElement {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
this.#runRules();
|
|
81
|
-
dispatchPublic(this, '
|
|
81
|
+
dispatchPublic(this, 'qc-item-set-outcomes', {
|
|
82
82
|
outcomes: copy.variables
|
|
83
83
|
.filter(v => v.type === 'outcome' || v.identifier === 'numAttempts')
|
|
84
84
|
.map(({ identifier, value }) => ({ identifier, value })),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-response-processing.js","sourceRoot":"","sources":["../../../src/components/qti-response-processing/qti-response-processing.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContextConsumer, ContextProvider } from '@lit/context';\nimport { css, html, LitElement } from 'lit';\n\nimport { itemContext, QtiExitResponseSignal, type QtiRuleBase } from '@qti-components/base';\n\nimport { mapResponse, mapResponsePoint, matchCorrect } from '../../internal/template-strings';\nimport { dispatchPublic } from '../../public-events';\n\nimport type { ItemContext, OutcomeVariable } from '@qti-components/base';\nimport type { PropertyValueMap } from 'lit';\n\ntype OutcomeValue = string | string[] | null | undefined;\n\n/** The response processing templates we substitute for, keyed by the file name in `template`. */\nconst responseProcessingTemplates: Record<string, string> = {\n map_response: mapResponse,\n map_response_point: mapResponsePoint,\n match_correct: matchCorrect\n};\n\n/**\n * Response processing as the item's own backend: it reads the item context, runs its rules once and\n * sends the outcomes and the attempt count back in one `cito-item-set-outcomes`. The item applies\n * them; a host that scores elsewhere sends the same event instead.\n */\nexport class QtiResponseProcessing extends LitElement {\n static override styles = [\n css`\n :host {\n display: none;\n }\n `\n ];\n\n /**\n * The rules inside read and write this element's copy of the item context, never the item's. It\n * is provided under the same `itemContext`: the nearest provider wins, so every expression in\n * here gets the copy without knowing about it.\n */\n #provider = new ContextProvider(this, { context: itemContext });\n #copy?: ItemContext;\n\n constructor() {\n super();\n new ContextConsumer(this, {\n context: itemContext,\n subscribe: true,\n // Every variable its own object, so a write changes the copy and not the item's context.\n callback: context => {\n this.#copy = { ...context, variables: context.variables.map(v => ({ ...v })) };\n this.#provider.setValue(this.#copy);\n }\n });\n // Every rule that sets an outcome sits in here: the write lands in the copy, so a later rule\n // reads it, and never reaches the item (or the test above it, whose outcome processing listens\n // for the same name).\n this.addEventListener(\n 'qti-set-outcome-value',\n (e: CustomEvent<{ outcomeIdentifier: string; value: OutcomeValue }>) => {\n e.stopImmediatePropagation();\n const variable = this.#copy?.variables.find(v => v.identifier === e.detail.outcomeIdentifier);\n if (!variable) {\n console.warn(`Can not set qti-outcome-identifier: ${e.detail.outcomeIdentifier}, it is not available`);\n return;\n }\n const { value } = e.detail;\n variable.value = variable.cardinality === 'single' ? value : Array.isArray(value) ? value : [value];\n }\n );\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n\n /**\n * Scores the attempt on the copy: sets `numAttempts` to the count the item hands over, resets a\n * non-adaptive item's outcomes to their defaults (QTI info model §2.5), runs the rules and sends\n * every outcome and `numAttempts` in one `cito-item-set-outcomes`. The item applies them and publishes, which gives this element a\n * fresh copy. A rule that throws ends the run and the error propagates; nothing is sent, and the\n * run's writes stay in the copy until the item's next update.\n */\n public processResponse({ numAttempts }: { numAttempts: number }): void {\n const copy = this.#copy;\n if (!copy) return;\n const reset = this.closest('qti-assessment-item')?.getAttribute('adaptive') !== 'true';\n for (const variable of copy.variables) {\n if (variable.identifier === 'numAttempts') variable.value = String(numAttempts);\n // completionStatus is built in: it has no default to reset to, and keeps its value (as in TAO).\n if (variable.type === 'outcome' && reset && variable.identifier !== 'completionStatus') {\n variable.value = defaultValueOf(variable as OutcomeVariable);\n }\n }\n\n this.#runRules();\n\n dispatchPublic(this, 'cito-item-set-outcomes', {\n outcomes: copy.variables\n .filter(v => v.type === 'outcome' || v.identifier === 'numAttempts')\n .map(({ identifier, value }) => ({ identifier, value })),\n responseProcessed: true\n });\n }\n\n #runRules() {\n const rules = [...this.children] as unknown as QtiRuleBase[];\n try {\n for (const rule of rules) {\n rule.process();\n }\n } catch (error) {\n // `qti-exit-response` ends the attempt's processing from wherever it\n // sits, however deeply nested. Reaching here is the rule doing its job,\n // so the run simply stops; anything else is a real failure and rethrows.\n if (!(error instanceof QtiExitResponseSignal)) throw error;\n }\n }\n\n public override firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {\n const template = this.getAttribute('template');\n if (!template) return;\n\n const templateName = template.split('/').pop()!.replace('.xml', '');\n const rules = responseProcessingTemplates[templateName];\n // Leave an unknown template's authored children alone; there is nothing to substitute.\n if (!rules) return;\n\n // Parsed through this element's own `innerHTML` rather than a fragment created off `document`:\n // the HTML fragment parsing algorithm takes its custom element registry from the context\n // element, so the rules are upgraded with the registry this element lives in. A fragment from\n // `document.createRange()` is parsed against the global registry, which leaves every rule an\n // unupgraded HTMLElement when the item was rendered into a scoped registry.\n this.innerHTML = rules;\n }\n}\n\n/** The declared default; a numeric outcome without one starts at 0. */\nfunction defaultValueOf(variable: OutcomeVariable): OutcomeValue {\n const value = ('defaultValue' in variable ? variable.defaultValue : null) ?? null;\n if (value === null && (variable.baseType === 'integer' || variable.baseType === 'float')) return '0';\n return value;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-response-processing': QtiResponseProcessing;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"qti-response-processing.js","sourceRoot":"","sources":["../../../src/components/qti-response-processing/qti-response-processing.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContextConsumer, ContextProvider } from '@lit/context';\nimport { css, html, LitElement } from 'lit';\n\nimport { itemContext, QtiExitResponseSignal, type QtiRuleBase } from '@qti-components/base';\n\nimport { mapResponse, mapResponsePoint, matchCorrect } from '../../internal/template-strings';\nimport { dispatchPublic } from '../../public-events';\n\nimport type { ItemContext, OutcomeVariable } from '@qti-components/base';\nimport type { PropertyValueMap } from 'lit';\n\ntype OutcomeValue = string | string[] | null | undefined;\n\n/** The response processing templates we substitute for, keyed by the file name in `template`. */\nconst responseProcessingTemplates: Record<string, string> = {\n map_response: mapResponse,\n map_response_point: mapResponsePoint,\n match_correct: matchCorrect\n};\n\n/**\n * Response processing as the item's own backend: it reads the item context, runs its rules once and\n * sends the outcomes and the attempt count back in one `qc-item-set-outcomes`. The item applies\n * them; a host that scores elsewhere sends the same event instead.\n */\nexport class QtiResponseProcessing extends LitElement {\n static override styles = [\n css`\n :host {\n display: none;\n }\n `\n ];\n\n /**\n * The rules inside read and write this element's copy of the item context, never the item's. It\n * is provided under the same `itemContext`: the nearest provider wins, so every expression in\n * here gets the copy without knowing about it.\n */\n #provider = new ContextProvider(this, { context: itemContext });\n #copy?: ItemContext;\n\n constructor() {\n super();\n new ContextConsumer(this, {\n context: itemContext,\n subscribe: true,\n // Every variable its own object, so a write changes the copy and not the item's context.\n callback: context => {\n this.#copy = { ...context, variables: context.variables.map(v => ({ ...v })) };\n this.#provider.setValue(this.#copy);\n }\n });\n // Every rule that sets an outcome sits in here: the write lands in the copy, so a later rule\n // reads it, and never reaches the item (or the test above it, whose outcome processing listens\n // for the same name).\n this.addEventListener(\n 'qti-set-outcome-value',\n (e: CustomEvent<{ outcomeIdentifier: string; value: OutcomeValue }>) => {\n e.stopImmediatePropagation();\n const variable = this.#copy?.variables.find(v => v.identifier === e.detail.outcomeIdentifier);\n if (!variable) {\n console.warn(`Can not set qti-outcome-identifier: ${e.detail.outcomeIdentifier}, it is not available`);\n return;\n }\n const { value } = e.detail;\n variable.value = variable.cardinality === 'single' ? value : Array.isArray(value) ? value : [value];\n }\n );\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n\n /**\n * Scores the attempt on the copy: sets `numAttempts` to the count the item hands over, resets a\n * non-adaptive item's outcomes to their defaults (QTI info model §2.5), runs the rules and sends\n * every outcome and `numAttempts` in one `qc-item-set-outcomes`. The item applies them and publishes, which gives this element a\n * fresh copy. A rule that throws ends the run and the error propagates; nothing is sent, and the\n * run's writes stay in the copy until the item's next update.\n */\n public processResponse({ numAttempts }: { numAttempts: number }): void {\n const copy = this.#copy;\n if (!copy) return;\n const reset = this.closest('qti-assessment-item')?.getAttribute('adaptive') !== 'true';\n for (const variable of copy.variables) {\n if (variable.identifier === 'numAttempts') variable.value = String(numAttempts);\n // completionStatus is built in: it has no default to reset to, and keeps its value (as in TAO).\n if (variable.type === 'outcome' && reset && variable.identifier !== 'completionStatus') {\n variable.value = defaultValueOf(variable as OutcomeVariable);\n }\n }\n\n this.#runRules();\n\n dispatchPublic(this, 'qc-item-set-outcomes', {\n outcomes: copy.variables\n .filter(v => v.type === 'outcome' || v.identifier === 'numAttempts')\n .map(({ identifier, value }) => ({ identifier, value })),\n responseProcessed: true\n });\n }\n\n #runRules() {\n const rules = [...this.children] as unknown as QtiRuleBase[];\n try {\n for (const rule of rules) {\n rule.process();\n }\n } catch (error) {\n // `qti-exit-response` ends the attempt's processing from wherever it\n // sits, however deeply nested. Reaching here is the rule doing its job,\n // so the run simply stops; anything else is a real failure and rethrows.\n if (!(error instanceof QtiExitResponseSignal)) throw error;\n }\n }\n\n public override firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {\n const template = this.getAttribute('template');\n if (!template) return;\n\n const templateName = template.split('/').pop()!.replace('.xml', '');\n const rules = responseProcessingTemplates[templateName];\n // Leave an unknown template's authored children alone; there is nothing to substitute.\n if (!rules) return;\n\n // Parsed through this element's own `innerHTML` rather than a fragment created off `document`:\n // the HTML fragment parsing algorithm takes its custom element registry from the context\n // element, so the rules are upgraded with the registry this element lives in. A fragment from\n // `document.createRange()` is parsed against the global registry, which leaves every rule an\n // unupgraded HTMLElement when the item was rendered into a scoped registry.\n this.innerHTML = rules;\n }\n}\n\n/** The declared default; a numeric outcome without one starts at 0. */\nfunction defaultValueOf(variable: OutcomeVariable): OutcomeValue {\n const value = ('defaultValue' in variable ? variable.defaultValue : null) ?? null;\n if (value === null && (variable.baseType === 'integer' || variable.baseType === 'float')) return '0';\n return value;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-response-processing': QtiResponseProcessing;\n }\n}\n"]}
|
|
@@ -15,7 +15,7 @@ export class QtiRubricBlock extends LitElement {
|
|
|
15
15
|
switch (className) {
|
|
16
16
|
case 'qti-rubric-discretionary-placement':
|
|
17
17
|
{
|
|
18
|
-
const notCancelled = dispatchPublic(this, '
|
|
18
|
+
const notCancelled = dispatchPublic(this, 'qc-item-rubric-placement', { className, element: this }, true);
|
|
19
19
|
if (!notCancelled)
|
|
20
20
|
return;
|
|
21
21
|
this.setAttribute('slot', 'qti-rubric-block');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-rubric-block.js","sourceRoot":"","sources":["../../../src/components/qti-rubric-block/qti-rubric-block.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,OAAO,cAAe,SAAQ,UAAU;IAS5C,sBAAsB;QACpB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9C,UAAU,CAAC,OAAO,CAAC,CAAC,SAAiB,EAAE,EAAE;YACvC,QAAQ,SAAS,EAAE,CAAC;gBAClB,KAAK,oCAAoC;oBACvC,CAAC;wBACC,MAAM,YAAY,GAAG,cAAc,CAAC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"qti-rubric-block.js","sourceRoot":"","sources":["../../../src/components/qti-rubric-block/qti-rubric-block.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,OAAO,cAAe,SAAQ,UAAU;IAS5C,sBAAsB;QACpB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9C,UAAU,CAAC,OAAO,CAAC,CAAC,SAAiB,EAAE,EAAE;YACvC,QAAQ,SAAS,EAAE,CAAC;gBAClB,KAAK,oCAAoC;oBACvC,CAAC;wBACC,MAAM,YAAY,GAAG,cAAc,CAAC,IAAI,EAAE,0BAA0B,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;wBAC1G,IAAI,CAAC,YAAY;4BAAE,OAAO;wBAC1B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;oBAChD,CAAC;oBACD,MAAM;gBACR,KAAK,mBAAmB;oBACtB,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;oBAC9B,MAAM;gBACR;oBACE,MAAM;YACV,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;aAEe,WAAM,GAAG,GAAG,CAAA;;;;GAI3B,CAAC;IAEO,MAAM;QACb,OAAO,IAAI,CAAA,eAAe,CAAC;IAC7B,CAAC;;AApCoC;IAApC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CAAqB;AAEpB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CAAgD;AAE/C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CAAmF;AAE9D;IAA/C,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;kDAAoB;AAEnE;IADC,KAAK,CAAC,YAAY,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;4DAmBnD","sourcesContent":["import { LitElement, css, html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { watch } from '@qti-components/utilities';\n\nimport { dispatchPublic } from '../../public-events';\n\nexport class QtiRubricBlock extends LitElement {\n @property({ type: String }) override id: string; // =\"qtiAspectInhoudRubricBlock\"\n\n @property({ type: String }) use: 'instructions' | 'scoring' | 'navigation'; // = \"scoring\"\n\n @property({ type: String }) view: 'author' | 'candidate' | 'proctor' | 'scorer' | 'testConstructor' | 'tutor';\n\n @property({ type: String, attribute: 'class' }) classNames: string;\n @watch('classNames', { waitUntilFirstUpdate: true })\n handleclassNamesChange() {\n const classNames = this.classNames.split(' ');\n classNames.forEach((className: string) => {\n switch (className) {\n case 'qti-rubric-discretionary-placement':\n {\n const notCancelled = dispatchPublic(this, 'qc-item-rubric-placement', { className, element: this }, true);\n if (!notCancelled) return;\n this.setAttribute('slot', 'qti-rubric-block');\n }\n break;\n case 'qti-rubric-inline':\n this.setAttribute('slot', '');\n break;\n default:\n break;\n }\n });\n }\n\n static override styles = css`\n :host {\n display: block;\n }\n `;\n\n override render() {\n return html`<slot></slot>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-rubric-block': QtiRubricBlock;\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FeedbackEventDetail } from '../public-events';
|
|
2
|
+
interface FeedbackElement extends Element {
|
|
3
|
+
outcomeIdentifier: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Send `qc-feedback-show` or `qc-feedback-hide` from a feedback element, just before it shows or
|
|
7
|
+
* hides. Both are cancelable; this returns `false` when the host cancels, i.e. takes over.
|
|
8
|
+
*/
|
|
9
|
+
export declare function dispatchFeedback(element: FeedbackElement, name: 'qc-feedback-show' | 'qc-feedback-hide', kind: FeedbackEventDetail['kind'], identifier: string): boolean;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { dispatchPublic } from '../public-events';
|
|
2
|
+
/**
|
|
3
|
+
* Send `qc-feedback-show` or `qc-feedback-hide` from a feedback element, just before it shows or
|
|
4
|
+
* hides. Both are cancelable; this returns `false` when the host cancels, i.e. takes over.
|
|
5
|
+
*/
|
|
6
|
+
export function dispatchFeedback(element, name, kind, identifier) {
|
|
7
|
+
const itemIdentifier = element.closest('qti-assessment-item')?.getAttribute('identifier') ?? undefined;
|
|
8
|
+
const detail = {
|
|
9
|
+
kind,
|
|
10
|
+
identifier,
|
|
11
|
+
outcomeIdentifier: element.outcomeIdentifier,
|
|
12
|
+
element,
|
|
13
|
+
...(itemIdentifier ? { itemIdentifier } : {})
|
|
14
|
+
};
|
|
15
|
+
return dispatchPublic(element, name, detail, true);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=feedback-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback-events.js","sourceRoot":"","sources":["../../src/internal/feedback-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAQlD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAwB,EACxB,IAA6C,EAC7C,IAAiC,EACjC,UAAkB;IAElB,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC;IACvG,MAAM,MAAM,GAAwB;QAClC,IAAI;QACJ,UAAU;QACV,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,OAAO;QACP,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC;IACF,OAAO,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AACrD,CAAC","sourcesContent":["import { dispatchPublic } from '../public-events';\n\nimport type { FeedbackEventDetail } from '../public-events';\n\ninterface FeedbackElement extends Element {\n outcomeIdentifier: string;\n}\n\n/**\n * Send `qc-feedback-show` or `qc-feedback-hide` from a feedback element, just before it shows or\n * hides. Both are cancelable; this returns `false` when the host cancels, i.e. takes over.\n */\nexport function dispatchFeedback(\n element: FeedbackElement,\n name: 'qc-feedback-show' | 'qc-feedback-hide',\n kind: FeedbackEventDetail['kind'],\n identifier: string\n): boolean {\n const itemIdentifier = element.closest('qti-assessment-item')?.getAttribute('identifier') ?? undefined;\n const detail: FeedbackEventDetail = {\n kind,\n identifier,\n outcomeIdentifier: element.outcomeIdentifier,\n element,\n ...(itemIdentifier ? { itemIdentifier } : {})\n };\n return dispatchPublic(element, name, detail, true);\n}\n"]}
|
package/dist/public-events.d.ts
CHANGED
|
@@ -1,36 +1,56 @@
|
|
|
1
1
|
import type { InteractionChangedDetails, OutcomeChangedDetails, OutcomesChangedDetails, SetOutcomesDetails } from './internal/event-types';
|
|
2
2
|
/**
|
|
3
3
|
* The public events of the item. The name tells you it is public: everything declared here starts
|
|
4
|
-
* with `
|
|
4
|
+
* with `qc-`; every other event is internal plumbing and may change in any release.
|
|
5
5
|
*
|
|
6
6
|
* Requests are verbs, notifications are past tense. All bubble and are composed.
|
|
7
7
|
*
|
|
8
|
-
* `deprecated` is the name the event had
|
|
9
|
-
*
|
|
8
|
+
* `deprecated` is the `cito-` name the event had in 9.x. `dispatchPublic` sends and `listenPublic`
|
|
9
|
+
* handles both until the next major, then the field goes. The 7.x names (`qti-interaction-changed`,
|
|
10
|
+
* `qti-outcome-changed`, `qti-rubric:discretionary-placement`) are no longer sent or handled.
|
|
10
11
|
*/
|
|
11
12
|
export interface PublicEventDeclaration {
|
|
12
13
|
kind: 'request' | 'notification';
|
|
13
14
|
scope: 'test' | 'item';
|
|
14
|
-
/** The name
|
|
15
|
+
/** The previous name. Dispatched and handled alongside the new one. */
|
|
15
16
|
deprecated?: string;
|
|
16
17
|
}
|
|
17
18
|
export interface RubricPlacement {
|
|
18
19
|
className: string;
|
|
19
20
|
element: Element;
|
|
20
21
|
}
|
|
22
|
+
/** The detail of `qc-feedback-show` and `qc-feedback-hide`. */
|
|
23
|
+
export interface FeedbackEventDetail {
|
|
24
|
+
kind: 'block' | 'inline' | 'modal';
|
|
25
|
+
/** The feedback's `identifier`. */
|
|
26
|
+
identifier: string;
|
|
27
|
+
/** The outcome it follows (`outcome-identifier`). */
|
|
28
|
+
outcomeIdentifier: string;
|
|
29
|
+
/** The feedback element itself: read or clone its content (it stays in the DOM, hidden). */
|
|
30
|
+
element: Element;
|
|
31
|
+
/** The identifier of the item it is in, when it is in one. */
|
|
32
|
+
itemIdentifier?: string;
|
|
33
|
+
}
|
|
21
34
|
export interface PublicItemEventMap {
|
|
22
|
-
'
|
|
35
|
+
'qc-item-response-changed': CustomEvent<InteractionChangedDetails>;
|
|
23
36
|
/**
|
|
24
37
|
* Request: the item applies these outcomes in one update. Response processing sends it; a host
|
|
25
38
|
* that scores on a backend sends it on the item with the outcomes the backend returned.
|
|
26
39
|
*/
|
|
27
|
-
'
|
|
40
|
+
'qc-item-set-outcomes': CustomEvent<SetOutcomesDetails>;
|
|
28
41
|
/** One per outcome an update applied, with its final value, after the item context is published. */
|
|
29
|
-
'
|
|
42
|
+
'qc-item-outcome-changed': CustomEvent<OutcomeChangedDetails>;
|
|
30
43
|
/** All the outcomes one update applied, after the item context is published. */
|
|
31
|
-
'
|
|
44
|
+
'qc-item-outcomes-changed': CustomEvent<OutcomesChangedDetails>;
|
|
32
45
|
/** Cancelable: `preventDefault()` keeps the rubric block where it is. */
|
|
33
|
-
'
|
|
46
|
+
'qc-item-rubric-placement': CustomEvent<RubricPlacement>;
|
|
47
|
+
/**
|
|
48
|
+
* Cancelable: the feedback element is about to show (its condition turned true). `preventDefault()`
|
|
49
|
+
* keeps it hidden, so the host can show the content itself. Sent once per showing.
|
|
50
|
+
*/
|
|
51
|
+
'qc-feedback-show': CustomEvent<FeedbackEventDetail>;
|
|
52
|
+
/** The condition of a feedback that was shown (or taken over by the host) turned false again. */
|
|
53
|
+
'qc-feedback-hide': CustomEvent<FeedbackEventDetail>;
|
|
34
54
|
}
|
|
35
55
|
export type PublicItemEventName = keyof PublicItemEventMap;
|
|
36
56
|
export declare const PUBLIC_ITEM_EVENTS: Record<PublicItemEventName, PublicEventDeclaration>;
|
package/dist/public-events.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
export const PUBLIC_ITEM_EVENTS = {
|
|
2
2
|
// The old name `qti-assessment-item-connected` stays as internal plumbing: it is sent separately.
|
|
3
|
-
'
|
|
4
|
-
'
|
|
5
|
-
'
|
|
6
|
-
'
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
deprecated: 'qti-rubric:discretionary-placement'
|
|
12
|
-
}
|
|
3
|
+
'qc-item-rendered': { kind: 'notification', scope: 'item', deprecated: 'cito-item-rendered' },
|
|
4
|
+
'qc-item-response-changed': { kind: 'notification', scope: 'item', deprecated: 'cito-item-response-changed' },
|
|
5
|
+
'qc-item-set-outcomes': { kind: 'request', scope: 'item', deprecated: 'cito-item-set-outcomes' },
|
|
6
|
+
'qc-item-outcome-changed': { kind: 'notification', scope: 'item', deprecated: 'cito-item-outcome-changed' },
|
|
7
|
+
'qc-item-outcomes-changed': { kind: 'notification', scope: 'item', deprecated: 'cito-item-outcomes-changed' },
|
|
8
|
+
'qc-item-rubric-placement': { kind: 'notification', scope: 'item', deprecated: 'cito-item-rubric-placement' },
|
|
9
|
+
'qc-feedback-show': { kind: 'notification', scope: 'item', deprecated: 'cito-feedback-show' },
|
|
10
|
+
'qc-feedback-hide': { kind: 'notification', scope: 'item', deprecated: 'cito-feedback-hide' }
|
|
13
11
|
};
|
|
14
12
|
/**
|
|
15
13
|
* Dispatch `name` and its deprecated name with the same `detail` object, new name first. Returns
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-events.js","sourceRoot":"","sources":["../src/public-events.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"public-events.js","sourceRoot":"","sources":["../src/public-events.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n InteractionChangedDetails,\n OutcomeChangedDetails,\n OutcomesChangedDetails,\n SetOutcomesDetails\n} from './internal/event-types';\n\n/**\n * The public events of the item. The name tells you it is public: everything declared here starts\n * with `qc-`; every other event is internal plumbing and may change in any release.\n *\n * Requests are verbs, notifications are past tense. All bubble and are composed.\n *\n * `deprecated` is the `cito-` name the event had in 9.x. `dispatchPublic` sends and `listenPublic`\n * handles both until the next major, then the field goes. The 7.x names (`qti-interaction-changed`,\n * `qti-outcome-changed`, `qti-rubric:discretionary-placement`) are no longer sent or handled.\n */\nexport interface PublicEventDeclaration {\n kind: 'request' | 'notification';\n scope: 'test' | 'item';\n /** The previous name. Dispatched and handled alongside the new one. */\n deprecated?: string;\n}\n\nexport interface RubricPlacement {\n className: string;\n element: Element;\n}\n\n/** The detail of `qc-feedback-show` and `qc-feedback-hide`. */\nexport interface FeedbackEventDetail {\n kind: 'block' | 'inline' | 'modal';\n /** The feedback's `identifier`. */\n identifier: string;\n /** The outcome it follows (`outcome-identifier`). */\n outcomeIdentifier: string;\n /** The feedback element itself: read or clone its content (it stays in the DOM, hidden). */\n element: Element;\n /** The identifier of the item it is in, when it is in one. */\n itemIdentifier?: string;\n}\n\nexport interface PublicItemEventMap {\n // `qc-item-rendered` (detail: the `QtiAssessmentItem`) is added by qti-assessment-item.ts, so this\n // module imports no element: that import would be a cycle.\n 'qc-item-response-changed': CustomEvent<InteractionChangedDetails>;\n /**\n * Request: the item applies these outcomes in one update. Response processing sends it; a host\n * that scores on a backend sends it on the item with the outcomes the backend returned.\n */\n 'qc-item-set-outcomes': CustomEvent<SetOutcomesDetails>;\n /** One per outcome an update applied, with its final value, after the item context is published. */\n 'qc-item-outcome-changed': CustomEvent<OutcomeChangedDetails>;\n /** All the outcomes one update applied, after the item context is published. */\n 'qc-item-outcomes-changed': CustomEvent<OutcomesChangedDetails>;\n /** Cancelable: `preventDefault()` keeps the rubric block where it is. */\n 'qc-item-rubric-placement': CustomEvent<RubricPlacement>;\n /**\n * Cancelable: the feedback element is about to show (its condition turned true). `preventDefault()`\n * keeps it hidden, so the host can show the content itself. Sent once per showing.\n */\n 'qc-feedback-show': CustomEvent<FeedbackEventDetail>;\n /** The condition of a feedback that was shown (or taken over by the host) turned false again. */\n 'qc-feedback-hide': CustomEvent<FeedbackEventDetail>;\n}\n\nexport type PublicItemEventName = keyof PublicItemEventMap;\n\nexport const PUBLIC_ITEM_EVENTS: Record<PublicItemEventName, PublicEventDeclaration> = {\n // The old name `qti-assessment-item-connected` stays as internal plumbing: it is sent separately.\n 'qc-item-rendered': { kind: 'notification', scope: 'item', deprecated: 'cito-item-rendered' },\n 'qc-item-response-changed': { kind: 'notification', scope: 'item', deprecated: 'cito-item-response-changed' },\n 'qc-item-set-outcomes': { kind: 'request', scope: 'item', deprecated: 'cito-item-set-outcomes' },\n 'qc-item-outcome-changed': { kind: 'notification', scope: 'item', deprecated: 'cito-item-outcome-changed' },\n 'qc-item-outcomes-changed': { kind: 'notification', scope: 'item', deprecated: 'cito-item-outcomes-changed' },\n 'qc-item-rubric-placement': { kind: 'notification', scope: 'item', deprecated: 'cito-item-rubric-placement' },\n 'qc-feedback-show': { kind: 'notification', scope: 'item', deprecated: 'cito-feedback-show' },\n 'qc-feedback-hide': { kind: 'notification', scope: 'item', deprecated: 'cito-feedback-hide' }\n};\n\ndeclare global {\n interface HTMLElementEventMap extends PublicItemEventMap {}\n}\n\n/**\n * Dispatch `name` and its deprecated name with the same `detail` object, new name first. Returns\n * `false` when a listener of either cancelled the event. The detail is always an object.\n * Shared by the item and test tiers; use `dispatchPublic` (item) or the test's own wrapper.\n */\nexport function dispatchDeclared(\n target: EventTarget,\n declarations: Record<string, PublicEventDeclaration>,\n name: string,\n detail: unknown,\n cancelable = false\n): boolean {\n const init = { detail: detail ?? {}, bubbles: true, composed: true, cancelable };\n const notCancelled = target.dispatchEvent(new CustomEvent(name, init));\n const { deprecated } = declarations[name];\n if (!deprecated) return notCancelled;\n return target.dispatchEvent(new CustomEvent(deprecated, init)) && notCancelled;\n}\n\nconst warned = new Set<string>();\n\n/**\n * Listen for `name` and its deprecated name. `dispatchDeclared` sends the old name straight after\n * the new one, synchronously, with the same `detail`: that one is skipped, so the handler runs\n * once. A host that sends only the old name is handled too, and warned once per name in the\n * console: only a sender outside our own components gets here without the new name before it.\n */\nexport function listenDeclared(\n target: EventTarget,\n declarations: Record<string, PublicEventDeclaration>,\n name: string,\n handler: (e: Event) => void\n): void {\n let justHandled: unknown;\n target.addEventListener(name, e => {\n justHandled = (e as CustomEvent).detail;\n queueMicrotask(() => (justHandled = undefined));\n handler(e);\n });\n const { deprecated } = declarations[name];\n if (deprecated) {\n target.addEventListener(deprecated, e => {\n if (justHandled !== undefined && (e as CustomEvent).detail === justHandled) return;\n if (!warned.has(deprecated)) {\n warned.add(deprecated);\n console.warn(`[qti-components] The event \"${deprecated}\" is deprecated; dispatch \"${name}\" instead.`);\n }\n handler(e);\n });\n }\n}\n\nexport function dispatchPublic<K extends PublicItemEventName>(\n target: EventTarget,\n name: K,\n detail: PublicItemEventMap[K] extends CustomEvent<infer D> ? D : never,\n cancelable = false\n): boolean {\n return dispatchDeclared(target, PUBLIC_ITEM_EVENTS, name, detail, cancelable);\n}\n\nexport function listenPublic<K extends PublicItemEventName>(\n target: EventTarget,\n name: K,\n handler: (e: PublicItemEventMap[K]) => void\n): void {\n listenDeclared(target, PUBLIC_ITEM_EVENTS, name, handler as (e: Event) => void);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qti-components/elements",
|
|
3
3
|
"description": "QTI elements utilities",
|
|
4
|
-
"version": "2.0.0-next.
|
|
4
|
+
"version": "2.0.0-next.7",
|
|
5
5
|
"author": "",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@qti-components/base": "^3.0.0-next.
|
|
8
|
-
"@qti-components/transformers": "^1.
|
|
7
|
+
"@qti-components/base": "^3.0.0-next.6",
|
|
8
|
+
"@qti-components/transformers": "^1.8.0-next.0",
|
|
9
9
|
"@qti-components/utilities": "^1.3.3"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|