Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
context:
'Tells the learner to complete the passage by choosing an option in each inline dropdown gap',
},
shortAnswer: {
message: 'Short answer only:',
context: 'Tells the learner to type their answer in a text entry interaction',
},
});

export default {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
>
<SafeHTML :html="itemBodyMarkup" />
</div>
<NumericKeypad :lang="lang" />
</template>
</div>

Expand All @@ -21,10 +22,12 @@

<script>

import { computed, inject, provide, watch } from 'vue';
import { computed, inject, provide, ref, watch } from 'vue';
import cloneDeep from 'lodash/cloneDeep';
import { createSafeHTML } from 'kolibri-common/components/SafeHTML';
import { themeTokens } from 'kolibri-design-system/lib/styles/theme';
import useKeypad from 'kolibri-common/composables/useKeypad';
import NumericKeypad from 'kolibri-common/components/NumericKeypad';
import { useQTIContext } from '../composables/useQTIContext';
import { getItemBodyGuides, numberPassageGaps } from '../utils/itemBodyGuidance';
import AnswerGuide from './AnswerGuide.vue';
Expand Down Expand Up @@ -66,6 +69,7 @@
components: {
AnswerGuide,
SafeHTML,
NumericKeypad,
},
setup(props) {
const itemBody = computed(() => {
Expand Down Expand Up @@ -98,6 +102,10 @@

const { responses, processResponses } = qtiContext;

const lang = inject('lang', ref(null));
// Hosts the shared keypad state
useKeypad();

function setFromAnswerState() {
for (const [id, variable] of Object.entries(responses.value)) {
if (id in injectedAnswerState.value && injectedAnswerState.value[id] != null) {
Expand Down Expand Up @@ -150,6 +158,7 @@
itemBodyMarkup,
guides,
passageStyles,
lang,
};
},
props: {
Expand Down
2 changes: 2 additions & 0 deletions kolibri/plugins/qti_viewer/frontend/components/QTIViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@
environmentIdentifier: __version,
},
),
'lang',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: lang is never provided, so all numeral localization is dead code. Two independent defects on these two lines:

  1. They are the 3rd and 4th positional arguments to provide('QTI_CONTEXT', <computed>). Vue's provide(key, value) takes two arguments — these are silently dropped and no 'lang' key is ever registered.
  2. Even as a standalone call it would be undefined: this component declares no props option (grep -n props QTIViewer.vue returns only the setup(props, context) signature and this line), so props.lang is undefined.

Downstream, AssessmentItem.vue:105 and TextEntryInteraction.vue:117 both inject('lang', ref(null)) and get null. <NumericKeypad :lang="null"> renders ASCII glyphs, and localizeNumerals(lastCommittedRaw, undefined) at TextEntryInteraction.vue:257 no-ops — failing two #14992 acceptance criteria (localized keypad glyphs; report-mode redisplay in the content's numeral system).

The content language is already to hand: useContentViewer(context) returns lang (packages/kolibri/composables/useContentViewer.js:209), but the destructure at lines 38-47 omits it. Add lang there, drop these two stray arguments, and add a separate provide('lang', lang);.

computed(() => props.lang),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: lang is never provided, so all numeral localization is dead code. Two problems: (1) these two lines are extra positional args to provide('QTI_CONTEXT', <computed>) — Vue's provide(key, value) takes only two args, so 'lang' and its computed are silently dropped; (2) even as a standalone call, props.lang is undefined because QTIViewer declares no props (it's rendered by ContentViewer with only { on: … }). Consumers inject('lang', ref(null)) fall back to nullNumericKeypad shows ASCII glyphs and localizeNumerals(raw, undefined) no-ops. The content lang is already available from useContentViewer(context) (returns lang, see packages/kolibri/composables/useContentViewer.js:209), but the destructure at line 38 omits it. Fix: destructure lang and add a separate provide('lang', lang); call. Note the test helper renderAssessmentItem never provides lang, so this is invisible to the current suite.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: lang is never provided, so all numeral localization is dead code. (1) These two lines are passed as the 3rd/4th positional args to provide('QTI_CONTEXT', <computed>). provide(key, value) takes only two args, so 'lang' and its computed are silently dropped; no 'lang' key is registered. (2) Even standalone it would be undefined: QTIViewer declares no props, and useContentViewer is destructured without lang. Downstream AssessmentItem.vue:78 inject('lang', ref(null))null, so the keypad shows ASCII glyphs and report-mode localizeNumerals(raw, null) no-ops — failing two #14992 ACs. Fix: destructure lang from useContentViewer(context) (it returns it), drop these two stray args, and add a separate provide('lang', lang);.

);
provide(
Expand Down
Git LFS file not shown
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,10 @@ export default [
identifier: 'q20-textentry-sv-1',
title: 'Richard III',
},
{
identifier: 'q20-textentry-sv-1a',
title: 'Richard III - MathML',
},
],
},
{
Expand Down
Loading
Loading