[QTI] Editing a question drops content the editor doesn't model
维护者通常 1 天内回复
@rtibblesbot 已经在做这个了。
开始于 2026年10月16日。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 15/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- javascript, xml
- 领域
- frontend
调研方向
The bug is in _extractAnswers in interactions/textEntry/parse.js, which compares the trimmed qti-value with the untrimmed first map-key. Reproduce it with a Jest test using the declaration from the issue, then check that the output is [[' Paris', false], ['Paris', true], ['Paris', false]] and that opening the item emits no update:rawData. The issue states it is not open for contribution, so confirm with maintainers before starting.
由索引模型根据 Issue 内容生成。
描述
❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.
Target branch: unstable
Observed behavior
Saving any edit to a QTI question rewrites parts the editor doesn't model. isEditableItem (validateItem.js#L45-L127) checks only the root's attributes and children, so none of these open read-only:
- Interaction attributes: the builders write only what they set (textEntry/parse.js#L308-L320, choice/parse.js#L139-L145). Every converted legacy input question loses
placeholder-text="Enter your answer here"; a choice losesclass="qti-labels-upper-alpha". - Prefixed MathML in the prompt:
adoptNoderecreates<m:math>with its prefix (xml.js#L99-L103), which TipTap doesn't read as math.solve <m:math>…</m:math>.saves as<p>solve x+1.</p>. data-catalog-idrefin the prompt: TipTap drops the span.Pick the <span data-catalog-idref="g1">vowel</span>.saves as<p>Pick the vowel.</p>. Since #6306 an item that also holds the glossary<qti-catalog>opens read-only; one without it is still editable.- Text entry answers:
_extractAnswerscompares the trimmed<qti-value>with the untrimmed first map-key (textEntry/parse.js#L214-L224), so it reads answers by value. Map-keysParis,Paris(case-sensitive),Parisopen asParis,Paris.
Expected behavior
- An edit keeps everything it didn't touch.
User-facing consequences
- Learners see a question that differs from the uploaded one: no placeholder, no choice labels, no formula, no glossary term, or a dropped answer.
- The author isn't told.
Steps to reproduce
- Open a converted legacy input question (
input_question.xml), click Edit, change a hint, click Close:<qti-text-entry-interaction>has noplaceholder-text. - Open a single-choice item whose root declares
xmlns:m="http://www.w3.org/1998/Math/MathML"and whose prompt holds<m:math>…</m:math>, type at the end of the question text, click Close: the saved prompt has no<m:math>. - Open a single-choice item whose prompt is
Pick the <span data-catalog-idref="g1">vowel</span>.and holds no<qti-catalog>, add a hint, click Close: the saved prompt is<p>Pick the vowel.</p>. - Call
_extractAnswerson the declaration below: it returns[['Paris', false], [' Paris', false]].<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="string"> <qti-correct-response><qti-value> Paris</qti-value></qti-correct-response> <qti-mapping default-value="0"> <qti-map-entry map-key=" Paris" mapped-value="1" case-sensitive="false"/> <qti-map-entry map-key="Paris" mapped-value="1" case-sensitive="true"/> <qti-map-entry map-key="Paris" mapped-value="1" case-sensitive="false"/> </qti-mapping> </qti-response-declaration>
Acceptance Criteria
- Editing a converted text entry question keeps
placeholder-text; editing a choice question keepsclasson<qti-choice-interaction>. - Editing the prompt of an item with prefixed MathML saves the formula as MathML, and the item passes the XSD check.
- An item with
data-catalog-idrefin its prompt keeps it on save, or opens read-only. - The declaration above reads as
[[' Paris', false], ['Paris', true], ['Paris', false]], and opening that item emits noupdate:rawData. - Tests cover each case from opening the item to the emitted
raw_data.
Context
unstable at 98b560e08.
AI usage
rtibbles chose which issues to merge; Claude Code reproduced each case on unstable with Jest and drafted this issue, which merges #6287, #6307 and #6308.
- 主要语言
- Python
- 星标
- 213
- 派生
- 314
- 平均合并
- 2 天 20 小时
- 30 天内合并 PR
- 65
环境准备
- 提供 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
learningequality/studio 的其他 Issue
-
DEV: frontend P3 - low
难度 2/5 1-3 小时 新手友好度 74/100
learningequality/studio#5868 ·
维护者通常 1 天内回复
-
TAG: tech update / debt
难度 2/5 1-3 小时 新手友好度 62/100
learningequality/studio#2245 ·
维护者通常 1 天内回复
-
Turn on the KDS theming lint rules and move theme values out of inline styles可能已有人在做 @LianaHarris360 于 1 天前认领。 未关闭DEV: frontend P1 - important
learningequality/studio#6329 · 已指派 1 人 ·
维护者通常 1 天内回复
-
Upgrade kolibri-format to 3.0.1 and migrate ESLint to flat config可能已有人在做 @LianaHarris360 于 1 天前认领。 未关闭dependencies DEV: frontend P1 - important
learningequality/studio#6328 · 已指派 1 人 ·
维护者通常 1 天内回复
-
bug DEV: frontend P0 - critical
难度 4/5 3-5 天 新手友好度 25/100
learningequality/studio#6327 · 1 条评论 · 1 个 reaction ·
维护者通常 1 天内回复
查看 learningequality/studio 的全部 Issue
相似的 Issue
-
style: article/section 📝 system: cloud.rc ☁️ system: security 🔐
难度 2/5 1-3 小时 新手友好度 65/100
uabrc/uabrc.github.io#1262 ·
-
documentation
难度 2/5 1-3 小时 新手友好度 70/100
NCAR/miles-credit#526 ·
-
documentation
难度 1/5 1-3 小时 新手友好度 76/100
conda/conda-lock#957 ·
维护者通常 1 天内回复
-
Type: Bug
难度 2/5 1-3 小时 新手友好度 65/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
aws-samples/sample-per-model-bedrock#464 ·
维护者通常 1 天内回复