@longsightgroup/qti3-player 0.4.0 → 0.5.4

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.
Files changed (291) hide show
  1. package/README.md +146 -13
  2. package/dist/content/content-dom.d.ts +11 -0
  3. package/dist/content/content-dom.d.ts.map +1 -0
  4. package/dist/content/content-dom.js +262 -0
  5. package/dist/content/content-dom.js.map +1 -0
  6. package/dist/content/content-renderer.d.ts +17 -0
  7. package/dist/content/content-renderer.d.ts.map +1 -0
  8. package/dist/content/content-renderer.js +82 -0
  9. package/dist/content/content-renderer.js.map +1 -0
  10. package/dist/controls/remove-button.d.ts +3 -0
  11. package/dist/controls/remove-button.d.ts.map +1 -0
  12. package/dist/controls/remove-button.js +12 -0
  13. package/dist/controls/remove-button.js.map +1 -0
  14. package/dist/index.d.ts +13 -2
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +6 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/interactions/choice-interaction.d.ts +4 -0
  19. package/dist/interactions/choice-interaction.d.ts.map +1 -0
  20. package/dist/interactions/choice-interaction.js +81 -0
  21. package/dist/interactions/choice-interaction.js.map +1 -0
  22. package/dist/interactions/drawing-interaction.d.ts +6 -0
  23. package/dist/interactions/drawing-interaction.d.ts.map +1 -0
  24. package/dist/interactions/drawing-interaction.js +401 -0
  25. package/dist/interactions/drawing-interaction.js.map +1 -0
  26. package/dist/interactions/end-attempt-interaction.d.ts +4 -0
  27. package/dist/interactions/end-attempt-interaction.d.ts.map +1 -0
  28. package/dist/interactions/end-attempt-interaction.js +13 -0
  29. package/dist/interactions/end-attempt-interaction.js.map +1 -0
  30. package/dist/interactions/gap-match-interaction.d.ts +4 -0
  31. package/dist/interactions/gap-match-interaction.d.ts.map +1 -0
  32. package/dist/interactions/gap-match-interaction.js +277 -0
  33. package/dist/interactions/gap-match-interaction.js.map +1 -0
  34. package/dist/interactions/graphic-associate-interaction.d.ts +4 -0
  35. package/dist/interactions/graphic-associate-interaction.d.ts.map +1 -0
  36. package/dist/interactions/graphic-associate-interaction.js +297 -0
  37. package/dist/interactions/graphic-associate-interaction.js.map +1 -0
  38. package/dist/interactions/graphic-context.d.ts +3 -0
  39. package/dist/interactions/graphic-context.d.ts.map +1 -0
  40. package/dist/interactions/graphic-context.js +35 -0
  41. package/dist/interactions/graphic-context.js.map +1 -0
  42. package/dist/interactions/hotspot-interaction.d.ts +4 -0
  43. package/dist/interactions/hotspot-interaction.d.ts.map +1 -0
  44. package/dist/interactions/hotspot-interaction.js +68 -0
  45. package/dist/interactions/hotspot-interaction.js.map +1 -0
  46. package/dist/interactions/hottext-interaction.d.ts +3 -0
  47. package/dist/interactions/hottext-interaction.d.ts.map +1 -0
  48. package/dist/interactions/hottext-interaction.js +66 -0
  49. package/dist/interactions/hottext-interaction.js.map +1 -0
  50. package/dist/interactions/inline-choice-interaction.d.ts +4 -0
  51. package/dist/interactions/inline-choice-interaction.d.ts.map +1 -0
  52. package/dist/interactions/inline-choice-interaction.js +31 -0
  53. package/dist/interactions/inline-choice-interaction.js.map +1 -0
  54. package/dist/interactions/inline-controls.d.ts +6 -0
  55. package/dist/interactions/inline-controls.d.ts.map +1 -0
  56. package/dist/interactions/inline-controls.js +15 -0
  57. package/dist/interactions/inline-controls.js.map +1 -0
  58. package/dist/interactions/interaction-diagnostics.d.ts +7 -0
  59. package/dist/interactions/interaction-diagnostics.d.ts.map +1 -0
  60. package/dist/interactions/interaction-diagnostics.js +137 -0
  61. package/dist/interactions/interaction-diagnostics.js.map +1 -0
  62. package/dist/interactions/interaction-dispatch.d.ts +2 -0
  63. package/dist/interactions/interaction-dispatch.d.ts.map +1 -0
  64. package/dist/interactions/interaction-dispatch.js +2 -0
  65. package/dist/interactions/interaction-dispatch.js.map +1 -0
  66. package/dist/interactions/interaction-label.d.ts +4 -0
  67. package/dist/interactions/interaction-label.d.ts.map +1 -0
  68. package/dist/interactions/interaction-label.js +8 -0
  69. package/dist/interactions/interaction-label.js.map +1 -0
  70. package/dist/interactions/interaction-registry.d.ts +24 -0
  71. package/dist/interactions/interaction-registry.d.ts.map +1 -0
  72. package/dist/interactions/interaction-registry.js +138 -0
  73. package/dist/interactions/interaction-registry.js.map +1 -0
  74. package/dist/interactions/match-interaction.d.ts +4 -0
  75. package/dist/interactions/match-interaction.d.ts.map +1 -0
  76. package/dist/interactions/match-interaction.js +188 -0
  77. package/dist/interactions/match-interaction.js.map +1 -0
  78. package/dist/interactions/object-asset.d.ts +8 -0
  79. package/dist/interactions/object-asset.d.ts.map +1 -0
  80. package/dist/interactions/object-asset.js +182 -0
  81. package/dist/interactions/object-asset.js.map +1 -0
  82. package/dist/interactions/pair-interaction.d.ts +4 -0
  83. package/dist/interactions/pair-interaction.d.ts.map +1 -0
  84. package/dist/interactions/pair-interaction.js +125 -0
  85. package/dist/interactions/pair-interaction.js.map +1 -0
  86. package/dist/interactions/point-value.d.ts +16 -0
  87. package/dist/interactions/point-value.d.ts.map +1 -0
  88. package/dist/interactions/point-value.js +37 -0
  89. package/dist/interactions/point-value.js.map +1 -0
  90. package/dist/interactions/portable-custom-interaction.d.ts +16 -0
  91. package/dist/interactions/portable-custom-interaction.d.ts.map +1 -0
  92. package/dist/interactions/portable-custom-interaction.js +97 -0
  93. package/dist/interactions/portable-custom-interaction.js.map +1 -0
  94. package/dist/interactions/position-object-interaction.d.ts +4 -0
  95. package/dist/interactions/position-object-interaction.d.ts.map +1 -0
  96. package/dist/interactions/position-object-interaction.js +177 -0
  97. package/dist/interactions/position-object-interaction.js.map +1 -0
  98. package/dist/interactions/routing.d.ts +5 -0
  99. package/dist/interactions/routing.d.ts.map +1 -0
  100. package/dist/interactions/routing.js +24 -0
  101. package/dist/interactions/routing.js.map +1 -0
  102. package/dist/interactions/select-point-interaction.d.ts +4 -0
  103. package/dist/interactions/select-point-interaction.d.ts.map +1 -0
  104. package/dist/interactions/select-point-interaction.js +166 -0
  105. package/dist/interactions/select-point-interaction.js.map +1 -0
  106. package/dist/interactions/shared.d.ts +12 -0
  107. package/dist/interactions/shared.d.ts.map +1 -0
  108. package/dist/interactions/shared.js +65 -0
  109. package/dist/interactions/shared.js.map +1 -0
  110. package/dist/interactions/text-interaction.d.ts +6 -0
  111. package/dist/interactions/text-interaction.d.ts.map +1 -0
  112. package/dist/interactions/text-interaction.js +110 -0
  113. package/dist/interactions/text-interaction.js.map +1 -0
  114. package/dist/interactions/unsupported-interaction.d.ts +4 -0
  115. package/dist/interactions/unsupported-interaction.d.ts.map +1 -0
  116. package/dist/interactions/unsupported-interaction.js +23 -0
  117. package/dist/interactions/unsupported-interaction.js.map +1 -0
  118. package/dist/interactions/upload-interaction.d.ts +4 -0
  119. package/dist/interactions/upload-interaction.d.ts.map +1 -0
  120. package/dist/interactions/upload-interaction.js +10 -0
  121. package/dist/interactions/upload-interaction.js.map +1 -0
  122. package/dist/player/attempt-availability.d.ts +6 -0
  123. package/dist/player/attempt-availability.d.ts.map +1 -0
  124. package/dist/player/attempt-availability.js +27 -0
  125. package/dist/player/attempt-availability.js.map +1 -0
  126. package/dist/player/content-state.d.ts +19 -0
  127. package/dist/player/content-state.d.ts.map +1 -0
  128. package/dist/player/content-state.js +39 -0
  129. package/dist/player/content-state.js.map +1 -0
  130. package/dist/player/dynamic-body.d.ts +7 -0
  131. package/dist/player/dynamic-body.d.ts.map +1 -0
  132. package/dist/player/dynamic-body.js +28 -0
  133. package/dist/player/dynamic-body.js.map +1 -0
  134. package/dist/player/feedback-panel.d.ts +3 -0
  135. package/dist/player/feedback-panel.d.ts.map +1 -0
  136. package/dist/player/feedback-panel.js +14 -0
  137. package/dist/player/feedback-panel.js.map +1 -0
  138. package/dist/player/fetch-xml.d.ts +2 -0
  139. package/dist/player/fetch-xml.d.ts.map +1 -0
  140. package/dist/player/fetch-xml.js +10 -0
  141. package/dist/player/fetch-xml.js.map +1 -0
  142. package/dist/player/interaction-render.d.ts +14 -0
  143. package/dist/player/interaction-render.d.ts.map +1 -0
  144. package/dist/player/interaction-render.js +51 -0
  145. package/dist/player/interaction-render.js.map +1 -0
  146. package/dist/player/render-shell.d.ts +8 -0
  147. package/dist/player/render-shell.d.ts.map +1 -0
  148. package/dist/player/render-shell.js +37 -0
  149. package/dist/player/render-shell.js.map +1 -0
  150. package/dist/player/resolve-assets.d.ts +3 -0
  151. package/dist/player/resolve-assets.d.ts.map +1 -0
  152. package/dist/player/resolve-assets.js +12 -0
  153. package/dist/player/resolve-assets.js.map +1 -0
  154. package/dist/player/validation-messages.d.ts +17 -0
  155. package/dist/player/validation-messages.d.ts.map +1 -0
  156. package/dist/player/validation-messages.js +33 -0
  157. package/dist/player/validation-messages.js.map +1 -0
  158. package/dist/player-adapter.d.ts +62 -0
  159. package/dist/player-adapter.d.ts.map +1 -0
  160. package/dist/player-adapter.js +119 -0
  161. package/dist/player-adapter.js.map +1 -0
  162. package/dist/player-dev.d.ts +4 -0
  163. package/dist/player-dev.d.ts.map +1 -0
  164. package/dist/player-dev.js +14 -0
  165. package/dist/player-dev.js.map +1 -0
  166. package/dist/player-element.d.ts +14 -1
  167. package/dist/player-element.d.ts.map +1 -1
  168. package/dist/player-element.js +57 -5
  169. package/dist/player-element.js.map +1 -1
  170. package/dist/player-locale.d.ts +8 -3
  171. package/dist/player-locale.d.ts.map +1 -1
  172. package/dist/player-locale.js +16 -175
  173. package/dist/player-locale.js.map +1 -1
  174. package/dist/player-message-catalog-default.d.ts +4 -0
  175. package/dist/player-message-catalog-default.d.ts.map +1 -0
  176. package/dist/player-message-catalog-default.js +118 -0
  177. package/dist/player-message-catalog-default.js.map +1 -0
  178. package/dist/player-message-catalog-validate.d.ts +31 -0
  179. package/dist/player-message-catalog-validate.d.ts.map +1 -0
  180. package/dist/player-message-catalog-validate.js +327 -0
  181. package/dist/player-message-catalog-validate.js.map +1 -0
  182. package/dist/player-message-catalog.d.ts +18 -0
  183. package/dist/player-message-catalog.d.ts.map +1 -0
  184. package/dist/player-message-catalog.js +40 -0
  185. package/dist/player-message-catalog.js.map +1 -0
  186. package/dist/player-message-keys.d.ts +6 -0
  187. package/dist/player-message-keys.d.ts.map +1 -0
  188. package/dist/player-message-keys.js +7 -0
  189. package/dist/player-message-keys.js.map +1 -0
  190. package/dist/player-message-manifest.d.ts +272 -0
  191. package/dist/player-message-manifest.d.ts.map +1 -0
  192. package/dist/player-message-manifest.js +83 -0
  193. package/dist/player-message-manifest.js.map +1 -0
  194. package/dist/player-message-overrides.d.ts +3 -0
  195. package/dist/player-message-overrides.d.ts.map +1 -0
  196. package/dist/player-message-overrides.js +28 -0
  197. package/dist/player-message-overrides.js.map +1 -0
  198. package/dist/player-message-resolver.d.ts +31 -0
  199. package/dist/player-message-resolver.d.ts.map +1 -0
  200. package/dist/player-message-resolver.js +110 -0
  201. package/dist/player-message-resolver.js.map +1 -0
  202. package/dist/player-messages.d.ts +0 -38
  203. package/dist/player-messages.d.ts.map +1 -1
  204. package/dist/player-types.d.ts +12 -2
  205. package/dist/player-types.d.ts.map +1 -1
  206. package/dist/reorder/a11y.d.ts +7 -0
  207. package/dist/reorder/a11y.d.ts.map +1 -0
  208. package/dist/reorder/a11y.js +34 -0
  209. package/dist/reorder/a11y.js.map +1 -0
  210. package/dist/reorder/graphic-order-interaction.d.ts +4 -0
  211. package/dist/reorder/graphic-order-interaction.d.ts.map +1 -0
  212. package/dist/reorder/graphic-order-interaction.js +205 -0
  213. package/dist/reorder/graphic-order-interaction.js.map +1 -0
  214. package/dist/reorder/list-controls.d.ts +22 -0
  215. package/dist/reorder/list-controls.d.ts.map +1 -0
  216. package/dist/reorder/list-controls.js +75 -0
  217. package/dist/reorder/list-controls.js.map +1 -0
  218. package/dist/reorder/order-interaction.d.ts +4 -0
  219. package/dist/reorder/order-interaction.d.ts.map +1 -0
  220. package/dist/reorder/order-interaction.js +54 -0
  221. package/dist/reorder/order-interaction.js.map +1 -0
  222. package/dist/styles/base-styles.d.ts +2 -0
  223. package/dist/styles/base-styles.d.ts.map +1 -0
  224. package/dist/styles/base-styles.js +133 -0
  225. package/dist/styles/base-styles.js.map +1 -0
  226. package/dist/styles/choice-hottext-styles.d.ts +2 -0
  227. package/dist/styles/choice-hottext-styles.d.ts.map +1 -0
  228. package/dist/styles/choice-hottext-styles.js +76 -0
  229. package/dist/styles/choice-hottext-styles.js.map +1 -0
  230. package/dist/styles/control-styles.d.ts +2 -0
  231. package/dist/styles/control-styles.d.ts.map +1 -0
  232. package/dist/styles/control-styles.js +114 -0
  233. package/dist/styles/control-styles.js.map +1 -0
  234. package/dist/styles/drawing-styles.d.ts +2 -0
  235. package/dist/styles/drawing-styles.d.ts.map +1 -0
  236. package/dist/styles/drawing-styles.js +30 -0
  237. package/dist/styles/drawing-styles.js.map +1 -0
  238. package/dist/styles/gap-match-styles.d.ts +2 -0
  239. package/dist/styles/gap-match-styles.d.ts.map +1 -0
  240. package/dist/styles/gap-match-styles.js +33 -0
  241. package/dist/styles/gap-match-styles.js.map +1 -0
  242. package/dist/styles/graphic-styles.d.ts +2 -0
  243. package/dist/styles/graphic-styles.d.ts.map +1 -0
  244. package/dist/styles/graphic-styles.js +289 -0
  245. package/dist/styles/graphic-styles.js.map +1 -0
  246. package/dist/styles/match-pair-styles.d.ts +2 -0
  247. package/dist/styles/match-pair-styles.d.ts.map +1 -0
  248. package/dist/styles/match-pair-styles.js +62 -0
  249. package/dist/styles/match-pair-styles.js.map +1 -0
  250. package/dist/styles/text-slider-styles.d.ts +2 -0
  251. package/dist/styles/text-slider-styles.d.ts.map +1 -0
  252. package/dist/styles/text-slider-styles.js +35 -0
  253. package/dist/styles/text-slider-styles.js.map +1 -0
  254. package/package.json +8 -8
  255. package/src/controls/remove-button.ts +8 -5
  256. package/src/index.ts +61 -5
  257. package/src/interactions/choice-interaction.ts +6 -2
  258. package/src/interactions/drawing-interaction.ts +14 -9
  259. package/src/interactions/end-attempt-interaction.ts +3 -3
  260. package/src/interactions/gap-match-interaction.ts +32 -13
  261. package/src/interactions/graphic-associate-interaction.ts +15 -10
  262. package/src/interactions/hotspot-interaction.ts +10 -6
  263. package/src/interactions/inline-choice-interaction.ts +4 -4
  264. package/src/interactions/interaction-registry.ts +12 -12
  265. package/src/interactions/match-interaction.ts +9 -6
  266. package/src/interactions/pair-interaction.ts +22 -14
  267. package/src/interactions/position-object-interaction.ts +22 -13
  268. package/src/interactions/select-point-interaction.ts +25 -13
  269. package/src/interactions/shared.ts +21 -4
  270. package/src/interactions/text-interaction.ts +14 -4
  271. package/src/interactions/upload-interaction.ts +6 -3
  272. package/src/player/interaction-render.ts +4 -4
  273. package/src/player-adapter.ts +253 -0
  274. package/src/player-dev.ts +14 -0
  275. package/src/player-element.ts +78 -8
  276. package/src/player-locale.ts +28 -199
  277. package/src/player-message-catalog-default.ts +119 -0
  278. package/src/player-message-catalog-validate.ts +425 -0
  279. package/src/player-message-catalog.ts +72 -0
  280. package/src/player-message-keys.ts +12 -0
  281. package/src/player-message-manifest.ts +103 -0
  282. package/src/player-message-overrides.ts +38 -0
  283. package/src/player-message-resolver.ts +205 -0
  284. package/src/player-messages.ts +0 -30
  285. package/src/player-types.ts +15 -4
  286. package/src/reorder/a11y.ts +22 -7
  287. package/src/reorder/graphic-order-interaction.ts +23 -16
  288. package/src/reorder/list-controls.ts +8 -6
  289. package/src/reorder/order-interaction.ts +7 -5
  290. package/src/styles/base-styles.ts +20 -5
  291. package/src/styles/graphic-styles.ts +0 -6
package/README.md CHANGED
@@ -46,25 +46,126 @@ scoring is a convenience for validation, feedback, previews, and response snapsh
46
46
  High-stakes assessment systems must treat browser outcomes as untrusted and recompute
47
47
  scores server-side from authoritative QTI XML and trusted response variables.
48
48
 
49
- ## Player Chrome Messages
49
+ ## Player Chrome Messages (host-owned i18n)
50
50
 
51
- The player keeps authored QTI content language separate from player chrome such as
52
- remove buttons. Chrome language defaults to the player `languageOfInterface` property,
53
- the `language-of-interface` attribute, browser language, document language, then
54
- English. Hosts can override it when delivery settings require a fixed interface language.
51
+ The player keeps **authored QTI content** (prompts, choice labels, `title` on
52
+ end-attempt) separate from **player chrome** (remove buttons, aria labels, live-region
53
+ status, gap labels).
55
54
 
56
- Built-in catalogs are currently available for English, Spanish (`es-MX`, `es-ES`),
57
- Swedish (`sv-SE`), German (`de-DE`), Portuguese (`pt-BR`, `pt-PT`), and French
58
- (`fr-FR`, `fr-CA`).
55
+ Only **English** ships in the package. `language-of-interface="sv-SE"` does **not**
56
+ change chrome by itself; the host loads a locale file.
57
+
58
+ ### Locale files (recommended)
59
+
60
+ Harbor or an LMS maintains JSON (or ICU/Fluent exported to JSON) with the shape
61
+ `PlayerMessageCatalog`: a flat `strings` map, optional `interactionTypes`, and
62
+ `directions`. Copy `defaultPlayerMessageCatalog` from the package as the template; omit
63
+ keys you do not need to translate (missing keys fall back to English).
64
+
65
+ ```ts
66
+ import type { PlayerMessageCatalog } from "@longsightgroup/qti3-player";
67
+
68
+ const sv = (await fetch("/locales/player/sv-SE.json")).json() as PlayerMessageCatalog;
69
+
70
+ player.languageOfInterface = "sv-SE";
71
+ player.messageCatalog = sv;
72
+ await player.loadXml(xml);
73
+ ```
74
+
75
+ Example entries:
76
+
77
+ ```json
78
+ {
79
+ "locale": "sv-SE",
80
+ "strings": {
81
+ "remove": "Ta bort",
82
+ "removePair": "Ta bort {label}",
83
+ "associationPairLabel": "{source} med {target}",
84
+ "extendedTextCounter": "{characters} tecken, {words} ord",
85
+ "associationsMade.one": "{count} koppling skapad.",
86
+ "associationsMade.other": "{count} kopplingar skapade."
87
+ },
88
+ "interactionTypes": {
89
+ "graphicOrder": "Grafisk ordning"
90
+ },
91
+ "directions": { "up": "upp", "down": "ner", "left": "vänster", "right": "höger" }
92
+ }
93
+ ```
94
+
95
+ Templates use `{placeholder}` names. For English-style singular/plural, use
96
+ `messageKey.one` and `messageKey.other` (for example `associationsMade.one`). Languages
97
+ that do not inflect by count can use a single key (for example one `extendedTextCounter`
98
+ string for all counts).
99
+
100
+ Validate locale files in CI with `validatePlayerMessageCatalog()` — pass `JSON.parse` output
101
+ directly (`unknown`). Shape errors (non-object root, missing `strings`, numeric templates, bad
102
+ `directions` / `interactionTypes`) return diagnostics instead of throwing:
59
103
 
60
104
  ```ts
61
- player.languageOfInterface = "es-MX";
62
- player.messages = {
63
- remove: () => "Eliminar",
64
- removePair: ({ label }) => `Eliminar ${label}`,
65
- };
105
+ import { validatePlayerMessageCatalog } from "@longsightgroup/qti3-player";
106
+
107
+ const raw = JSON.parse(await readFile("locales/player/sv-SE.json", "utf8"));
108
+ const result = validatePlayerMessageCatalog(raw);
109
+ if (!result.valid) {
110
+ for (const issue of result.diagnostics) {
111
+ console.error(`${issue.code} ${issue.key}: ${issue.message}`);
112
+ }
113
+ process.exit(1);
114
+ }
66
115
  ```
67
116
 
117
+ Use `requireAllKeys: true` only for complete locale files forked from `defaultPlayerMessageCatalog`.
118
+ Partial delivery catalogs should omit that flag.
119
+
120
+ Reference exports:
121
+
122
+ - `PLAYER_MESSAGE_KEYS` — message ids from `PLAYER_MESSAGE_MANIFEST`
123
+ - `PLAYER_MESSAGE_STRING_KEYS` — all keys in `defaultPlayerMessageCatalog.strings`
124
+ - `defaultPlayerMessageCatalog` — English template to fork
125
+ - `allowedCatalogPlaceholders(entry)` — placeholders a template may use
126
+ - `requiredCatalogPlaceholders(catalogKey)` — placeholders required for that key per English default
127
+ - `createPlayerMessageResolver(catalog)` — canonical key-driven runtime API
128
+ - `PlayerMessageParams<K>` — typed params for `message(key, params)`
129
+
130
+ Resolver kinds in the manifest (hosts only edit `strings`; behavior is fixed):
131
+
132
+ | Resolver | Meaning |
133
+ | --------------------- | ---------------------------------------------------- |
134
+ | `plain` | Static string |
135
+ | `template` | `{placeholder}` interpolation from params |
136
+ | `plural` | Uses `key.one` / `key.other` when `count` is present |
137
+ | `typeLabel` | Interaction type short name from `interactionTypes` |
138
+ | `typeTemplate` | Template with `{typeName}` derived from `type` |
139
+ | `directionTemplate` | Template with localized `{direction}` |
140
+ | `extendedTextCounter` | `{characters}`, `{words}`, and unit plural helpers |
141
+
142
+ ### Runtime API
143
+
144
+ Chrome resolves to a key-driven `PlayerMessageResolver`:
145
+
146
+ ```ts
147
+ const messages = resolvePlayerMessages(locale, {}, catalog);
148
+
149
+ messages.message("remove");
150
+ messages.message("removePair", { label: pairLabel });
151
+ messages.message("associationsMade", { count: 2 });
152
+ ```
153
+
154
+ `createPlayerMessageResolver(catalog)` builds the same resolver directly from a locale file.
155
+
156
+ ### Per-message overrides
157
+
158
+ `player.messages` accepts `QtiPlayerMessageOverrides` — each key uses the same param types as
159
+ `message(key, params)` (for example `removePair: ({ label }) => ...`). Use only when a catalog
160
+ entry is not enough; composed strings (for example `removePair` using `associationPairLabel`
161
+ text) are easy to break.
162
+
163
+ ### Item language vs interface language
164
+
165
+ Do not copy item `xml:lang` onto `<qti-assessment-item-player lang="...">` unless you
166
+ intentionally want the player element's `lang` attribute to influence
167
+ `defaultPlayerLocale()`. Prefer `player.messageCatalog` for UI chrome.
168
+
68
169
  ## Portable Custom Interactions
69
170
 
70
171
  For `qti-portable-custom-interaction`, the player renders a
@@ -75,11 +176,43 @@ definition. Host code can attach a PCI runtime and send response/state updates b
75
176
  Production sandboxing, CSP, origin policy, and audit logging belong to the host delivery
76
177
  system.
77
178
 
179
+ ## Framework adapters
180
+
181
+ Optional React and Preact TSX wrappers ship as separate packages. They keep the web component as
182
+ the rendering primitive and only handle framework lifecycle wiring:
183
+
184
+ - `@longsightgroup/qti3-player-react`
185
+ - `@longsightgroup/qti3-player-preact`
186
+
187
+ Use the native element directly when you do not need React or Preact integration.
188
+
189
+ Local manual proof for the React adapter: from the repo root run
190
+ `pnpm dev:adapter-react` and open `/adapter-react.html` (linked from the main manual harness).
191
+
192
+ ## Clearing a loaded item
193
+
194
+ `clearItem()` (or omitting declarative `xml` on the adapters) removes rendered content and in-memory
195
+ session state. It does not emit `qti-statechange` or other player events because no item is loaded.
196
+ Hosts should treat the prop transition or imperative call as the source of truth.
197
+
198
+ Framework adapters treat `xml={undefined}` as a clear and `xml=""` as a load attempt. An empty
199
+ string shows the parse error view when the XML is invalid.
200
+
201
+ Restored `loadOptions.state` reload keys use JSON serialization: equivalent content with different
202
+ object references does not reload, but key order follows construction order and in-place mutation
203
+ without a reload key change is not detected.
204
+
78
205
  ## Styling
79
206
 
80
207
  The player uses light DOM and is style-neutral by design. Host applications can style
81
208
  the rendered `qti3-*` classes directly while preserving the item author's QTI shared
82
209
  vocabulary classes.
83
210
 
211
+ Screen-reader status lines (`.qti3-selection-summary`, `aria-live="polite"`) are
212
+ visually hidden by default so LMS shells do not show reorder or selection announcements
213
+ to sighted users. They remain available to assistive technology. Set
214
+ `data-show-live-regions` on `qti-assessment-item-player` only in local debug or harness
215
+ pages when you want those messages visible on screen.
216
+
84
217
  See the main repository README for the support matrix and release notes:
85
218
  https://github.com/LongsightGroup/qti3
@@ -0,0 +1,11 @@
1
+ import type { QtiContentNode, QtiValue } from "@longsightgroup/qti3-core";
2
+ export declare const unsafeContentElements: Set<string>;
3
+ export declare function contentElementName(qtiName: string): string | undefined;
4
+ export declare function createContentElement(name: string): HTMLElement | MathMLElement;
5
+ export declare function copySafeAttributes(element: Element, attributes: Record<string, string>): void;
6
+ export declare function applySharedAccessibilityVocabulary(element: Element, attributes: Record<string, string>): void;
7
+ export declare function isSafeUrl(value: string): boolean;
8
+ export declare function isResolvableAssetUrl(value: string): boolean;
9
+ export declare function formatPrintedValue(value: QtiValue, format?: string): string;
10
+ export declare function contentNodeText(node: QtiContentNode): string;
11
+ //# sourceMappingURL=content-dom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-dom.d.ts","sourceRoot":"","sources":["../../src/content/content-dom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AA2D1E,eAAO,MAAM,qBAAqB,aAA+B,CAAC;AA6ClE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQtE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,CAK9E;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAS7F;AAED,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,IAAI,CAeN;AAiFD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAYhD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAQ3D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAY3E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAI5D"}
@@ -0,0 +1,262 @@
1
+ const htmlContentElements = new Set([
2
+ "a",
3
+ "abbr",
4
+ "b",
5
+ "bdi",
6
+ "bdo",
7
+ "blockquote",
8
+ "br",
9
+ "caption",
10
+ "cite",
11
+ "code",
12
+ "dd",
13
+ "dfn",
14
+ "div",
15
+ "dl",
16
+ "dt",
17
+ "em",
18
+ "figcaption",
19
+ "figure",
20
+ "h1",
21
+ "h2",
22
+ "h3",
23
+ "h4",
24
+ "h5",
25
+ "h6",
26
+ "hr",
27
+ "i",
28
+ "img",
29
+ "kbd",
30
+ "li",
31
+ "ol",
32
+ "p",
33
+ "pre",
34
+ "q",
35
+ "rb",
36
+ "rbc",
37
+ "rp",
38
+ "rt",
39
+ "rtc",
40
+ "ruby",
41
+ "samp",
42
+ "small",
43
+ "span",
44
+ "strong",
45
+ "sub",
46
+ "sup",
47
+ "table",
48
+ "tbody",
49
+ "td",
50
+ "tfoot",
51
+ "th",
52
+ "thead",
53
+ "tr",
54
+ "ul",
55
+ "var",
56
+ ]);
57
+ export const unsafeContentElements = new Set(["script", "style"]);
58
+ const mathMlElements = new Set([
59
+ "math",
60
+ "maction",
61
+ "maligngroup",
62
+ "malignmark",
63
+ "menclose",
64
+ "merror",
65
+ "mfenced",
66
+ "mfrac",
67
+ "mglyph",
68
+ "mi",
69
+ "mlabeledtr",
70
+ "mlongdiv",
71
+ "mmultiscripts",
72
+ "mn",
73
+ "mo",
74
+ "mover",
75
+ "mpadded",
76
+ "mphantom",
77
+ "mroot",
78
+ "mrow",
79
+ "ms",
80
+ "mscarries",
81
+ "mscarry",
82
+ "msgroup",
83
+ "msline",
84
+ "mspace",
85
+ "msqrt",
86
+ "msrow",
87
+ "mstack",
88
+ "mstyle",
89
+ "msub",
90
+ "msubsup",
91
+ "msup",
92
+ "mtable",
93
+ "mtd",
94
+ "mtext",
95
+ "mtr",
96
+ "munder",
97
+ "munderover",
98
+ "semantics",
99
+ ]);
100
+ export function contentElementName(qtiName) {
101
+ if (qtiName === "qti-content-body" || qtiName === "qti-prompt")
102
+ return undefined;
103
+ if (htmlContentElements.has(qtiName) || mathMlElements.has(qtiName))
104
+ return qtiName;
105
+ if (qtiName === "object")
106
+ return "object";
107
+ if (qtiName === "qti-rubric-block")
108
+ return "section";
109
+ if (qtiName === "qti-template-block")
110
+ return "div";
111
+ if (qtiName === "qti-template-inline")
112
+ return "span";
113
+ return undefined;
114
+ }
115
+ export function createContentElement(name) {
116
+ if (mathMlElements.has(name)) {
117
+ return document.createElementNS("http://www.w3.org/1998/Math/MathML", name);
118
+ }
119
+ return document.createElement(name);
120
+ }
121
+ export function copySafeAttributes(element, attributes) {
122
+ for (const [name, value] of Object.entries(attributes)) {
123
+ if (!isSafeContentAttribute(name, value))
124
+ continue;
125
+ element.setAttribute(name, value);
126
+ if (name === "xml:lang" && !Object.hasOwn(attributes, "lang")) {
127
+ element.setAttribute("lang", value);
128
+ }
129
+ }
130
+ applySharedAccessibilityVocabulary(element, attributes);
131
+ }
132
+ export function applySharedAccessibilityVocabulary(element, attributes) {
133
+ for (const [name, value] of Object.entries(attributes)) {
134
+ const ariaName = qtiAriaAttributeName(name);
135
+ if (!ariaName || hasAttributeName(attributes, ariaName))
136
+ continue;
137
+ element.setAttribute(ariaName, value);
138
+ }
139
+ const suppressTts = attributeValue(attributes, "data-qti-suppress-tts");
140
+ if (suppressesScreenReaderSpeech(suppressTts) &&
141
+ !hasAttributeName(attributes, "aria-hidden") &&
142
+ !hasAttributeName(attributes, "data-qti-aria-hidden")) {
143
+ element.setAttribute("aria-hidden", "true");
144
+ }
145
+ }
146
+ function qtiAriaAttributeName(name) {
147
+ const normalizedName = name.toLowerCase();
148
+ const prefix = "data-qti-aria-";
149
+ if (!normalizedName.startsWith(prefix))
150
+ return undefined;
151
+ const suffix = normalizedName.slice(prefix.length);
152
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(suffix))
153
+ return undefined;
154
+ return `aria-${suffix}`;
155
+ }
156
+ function attributeValue(attributes, name) {
157
+ const normalizedName = name.toLowerCase();
158
+ const entry = Object.entries(attributes).find(([attributeName]) => attributeName.toLowerCase() === normalizedName);
159
+ return entry?.[1];
160
+ }
161
+ function hasAttributeName(attributes, name) {
162
+ return attributeValue(attributes, name) !== undefined;
163
+ }
164
+ function suppressesScreenReaderSpeech(value) {
165
+ if (!value)
166
+ return false;
167
+ const tokens = value
168
+ .toLowerCase()
169
+ .split(/[\s,]+/)
170
+ .filter(Boolean);
171
+ return tokens.includes("all") || tokens.includes("screen-reader");
172
+ }
173
+ function isSafeContentAttribute(name, value) {
174
+ const normalizedName = name.toLowerCase();
175
+ if (normalizedName.startsWith("on"))
176
+ return false;
177
+ if (normalizedName === "style")
178
+ return false;
179
+ if (normalizedName === "href" || normalizedName === "src" || normalizedName === "data") {
180
+ return isSafeUrl(value);
181
+ }
182
+ return (normalizedName === "alt" ||
183
+ normalizedName === "class" ||
184
+ normalizedName === "colspan" ||
185
+ normalizedName === "dir" ||
186
+ normalizedName === "headers" ||
187
+ normalizedName === "height" ||
188
+ normalizedName === "id" ||
189
+ normalizedName === "lang" ||
190
+ normalizedName === "role" ||
191
+ normalizedName === "rowspan" ||
192
+ normalizedName === "scope" ||
193
+ normalizedName === "title" ||
194
+ normalizedName === "type" ||
195
+ normalizedName === "width" ||
196
+ normalizedName === "xml:lang" ||
197
+ mathMlAttributeNames.has(normalizedName) ||
198
+ normalizedName.startsWith("aria-") ||
199
+ normalizedName.startsWith("data-"));
200
+ }
201
+ const mathMlAttributeNames = new Set([
202
+ "accent",
203
+ "accentunder",
204
+ "align",
205
+ "columnalign",
206
+ "display",
207
+ "fence",
208
+ "largeop",
209
+ "lspace",
210
+ "mathbackground",
211
+ "mathcolor",
212
+ "mathsize",
213
+ "mathvariant",
214
+ "movablelimits",
215
+ "rowalign",
216
+ "rspace",
217
+ "separator",
218
+ "stretchy",
219
+ ]);
220
+ export function isSafeUrl(value) {
221
+ return (value.startsWith("#") ||
222
+ value.startsWith("/") ||
223
+ value.startsWith("./") ||
224
+ value.startsWith("../") ||
225
+ value.startsWith("http://") ||
226
+ value.startsWith("https://") ||
227
+ value.startsWith("data:image/") ||
228
+ value.startsWith("data:audio/") ||
229
+ value.startsWith("data:video/"));
230
+ }
231
+ export function isResolvableAssetUrl(value) {
232
+ return (!value.startsWith("#") &&
233
+ !value.startsWith("data:") &&
234
+ !value.startsWith("blob:") &&
235
+ !value.startsWith("http://") &&
236
+ !value.startsWith("https://"));
237
+ }
238
+ export function formatPrintedValue(value, format) {
239
+ if (value === null || value === undefined)
240
+ return "";
241
+ const numericValue = typeof value === "number" ? value : typeof value === "string" ? Number(value) : Number.NaN;
242
+ if (Number.isFinite(numericValue) && format) {
243
+ const fixed = /^%\.(\d+)f$/.exec(format);
244
+ if (fixed)
245
+ return numericValue.toFixed(Number(fixed[1]));
246
+ if (format === "%d" || format === "%i")
247
+ return String(Math.trunc(numericValue));
248
+ }
249
+ if (Array.isArray(value))
250
+ return value.map((item) => String(item)).join(", ");
251
+ if (typeof value === "object")
252
+ return JSON.stringify(value);
253
+ return String(value);
254
+ }
255
+ export function contentNodeText(node) {
256
+ if (node.kind === "text")
257
+ return node.text;
258
+ if ("children" in node)
259
+ return node.children.map(contentNodeText).join("");
260
+ return "";
261
+ }
262
+ //# sourceMappingURL=content-dom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-dom.js","sourceRoot":"","sources":["../../src/content/content-dom.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { QtiContentNode, QtiInteraction, QtiValue } from "@longsightgroup/qti3-core";
2
+ export interface PlayerContentContext {
3
+ interactionAt(index: number): QtiInteraction | undefined;
4
+ renderBlockInteraction(interaction: QtiInteraction): HTMLElement;
5
+ renderEmbeddedInteraction(interaction: QtiInteraction): HTMLElement;
6
+ currentVariableValue(identifier: string): QtiValue;
7
+ mathTemplateValue(node: Extract<QtiContentNode, {
8
+ kind: "element";
9
+ }>): string | undefined;
10
+ isFeedbackVisible(node: Extract<QtiContentNode, {
11
+ kind: "feedback";
12
+ }>): boolean;
13
+ isTemplateContentVisible(element: HTMLElement): boolean;
14
+ }
15
+ export declare function renderContentNodes(nodes: QtiContentNode[], context: PlayerContentContext): Node[];
16
+ export declare function renderContentNode(node: QtiContentNode, context: PlayerContentContext): Node[];
17
+ //# sourceMappingURL=content-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-renderer.d.ts","sourceRoot":"","sources":["../../src/content/content-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAS1F,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IACzD,sBAAsB,CAAC,WAAW,EAAE,cAAc,GAAG,WAAW,CAAC;IACjE,yBAAyB,CAAC,WAAW,EAAE,cAAc,GAAG,WAAW,CAAC;IACpE,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnD,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1F,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC;IAChF,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;CACzD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI,EAAE,CAEjG;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI,EAAE,CA6C7F"}
@@ -0,0 +1,82 @@
1
+ import { contentElementName, copySafeAttributes, createContentElement, formatPrintedValue, unsafeContentElements, } from "./content-dom.js";
2
+ export function renderContentNodes(nodes, context) {
3
+ return nodes.flatMap((node) => renderContentNode(node, context));
4
+ }
5
+ export function renderContentNode(node, context) {
6
+ if (node.kind === "text")
7
+ return [document.createTextNode(node.text)];
8
+ if (node.kind === "interaction") {
9
+ const interaction = context.interactionAt(node.interactionIndex);
10
+ if (!interaction)
11
+ return [];
12
+ if (interaction.type === "inlineChoice" || interaction.type === "textEntry") {
13
+ return [context.renderEmbeddedInteraction(interaction)];
14
+ }
15
+ return [context.renderBlockInteraction(interaction)];
16
+ }
17
+ if (node.kind === "printedVariable") {
18
+ return [renderPrintedVariable(node.identifier, node.format, context)];
19
+ }
20
+ if (node.kind === "feedback")
21
+ return renderFeedbackContent(node, context);
22
+ if (node.qtiName === "qti-template-block" || node.qtiName === "qti-template-inline") {
23
+ return [renderTemplateContent(node, context)];
24
+ }
25
+ if (node.qtiName === "qti-position-object-stage") {
26
+ return renderContentNodes(node.children.filter((child) => !("qtiName" in child) || (child.qtiName !== "object" && child.qtiName !== "img")), context);
27
+ }
28
+ if (node.qtiName === "qti-prompt") {
29
+ const prompt = document.createElement("p");
30
+ copySafeAttributes(prompt, node.attributes);
31
+ prompt.classList.add("qti3-item-prompt");
32
+ prompt.append(...renderContentNodes(node.children, context));
33
+ return [prompt];
34
+ }
35
+ if (unsafeContentElements.has(node.qtiName))
36
+ return [];
37
+ const elementName = contentElementName(node.qtiName);
38
+ if (!elementName)
39
+ return renderContentNodes(node.children, context);
40
+ const element = createContentElement(elementName);
41
+ copySafeAttributes(element, node.attributes);
42
+ const mathTemplateValue = context.mathTemplateValue(node);
43
+ if (mathTemplateValue === undefined) {
44
+ element.append(...renderContentNodes(node.children, context));
45
+ }
46
+ else {
47
+ element.textContent = mathTemplateValue;
48
+ }
49
+ return [element];
50
+ }
51
+ function renderTemplateContent(node, context) {
52
+ const element = document.createElement(node.qtiName === "qti-template-block" ? "div" : "span");
53
+ copySafeAttributes(element, node.attributes);
54
+ element.classList.add(node.qtiName === "qti-template-block" ? "qti3-template-block" : "qti3-template-inline");
55
+ element.dataset.templateIdentifier = node.attributes["template-identifier"] ?? "";
56
+ element.dataset.templateValueIdentifier = node.attributes.identifier ?? "";
57
+ element.dataset.showHide = node.attributes["show-hide"] === "hide" ? "hide" : "show";
58
+ element.hidden = !context.isTemplateContentVisible(element);
59
+ element.append(...renderContentNodes(node.children, context));
60
+ return element;
61
+ }
62
+ function renderPrintedVariable(identifier, format, context) {
63
+ const output = document.createElement("output");
64
+ output.className = "qti3-printed-variable";
65
+ output.dataset.identifier = identifier;
66
+ if (format)
67
+ output.dataset.format = format;
68
+ output.value = formatPrintedValue(context.currentVariableValue(identifier), format);
69
+ output.textContent = output.value;
70
+ return output;
71
+ }
72
+ function renderFeedbackContent(node, context) {
73
+ const element = document.createElement(node.feedbackType === "block" ? "section" : "span");
74
+ element.className = `qti3-feedback-${node.feedbackType}`;
75
+ element.dataset.feedbackIdentifier = node.identifier;
76
+ element.dataset.outcomeIdentifier = node.outcomeIdentifier;
77
+ element.dataset.showHide = node.showHide;
78
+ element.hidden = !context.isFeedbackVisible(node);
79
+ element.append(...renderContentNodes(node.children, context));
80
+ return [element];
81
+ }
82
+ //# sourceMappingURL=content-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-renderer.js","sourceRoot":"","sources":["../../src/content/content-renderer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAY1B,MAAM,UAAU,kBAAkB,CAAC,KAAuB,EAAE,OAA6B;IACvF,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAoB,EAAE,OAA6B;IACnF,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACjE,IAAI,CAAC,WAAW;YAAE,OAAO,EAAE,CAAC;QAC5B,IAAI,WAAW,CAAC,IAAI,KAAK,cAAc,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC5E,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACpC,OAAO,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1E,IAAI,IAAI,CAAC,OAAO,KAAK,oBAAoB,IAAI,IAAI,CAAC,OAAO,KAAK,qBAAqB,EAAE,CAAC;QACpF,OAAO,CAAC,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,2BAA2B,EAAE,CAAC;QACjD,OAAO,kBAAkB,CACvB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAClB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,CAC5F,EACD,OAAO,CACR,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,YAAY,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC3C,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACvD,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrD,IAAI,CAAC,WAAW;QAAE,OAAO,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAClD,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7C,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,CAAC,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,WAAW,GAAG,iBAAiB,CAAC;IAC1C,CAAC;IACD,OAAO,CAAC,OAAO,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,qBAAqB,CAC5B,IAAkD,EAClD,OAA6B;IAE7B,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,KAAK,oBAAoB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC/F,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7C,OAAO,CAAC,SAAS,CAAC,GAAG,CACnB,IAAI,CAAC,OAAO,KAAK,oBAAoB,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,sBAAsB,CACvF,CAAC;IACF,OAAO,CAAC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,UAAU,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC;IAClF,OAAO,CAAC,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC;IAC3E,OAAO,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IACrF,OAAO,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC5D,OAAO,CAAC,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,qBAAqB,CAC5B,UAAkB,EAClB,MAA0B,EAC1B,OAA6B;IAE7B,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,CAAC,SAAS,GAAG,uBAAuB,CAAC;IAC3C,MAAM,CAAC,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;IACvC,IAAI,MAAM;QAAE,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;IAC3C,MAAM,CAAC,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,oBAAoB,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;IACpF,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;IAClC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,qBAAqB,CAC5B,IAAmD,EACnD,OAA6B;IAE7B,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC3F,OAAO,CAAC,SAAS,GAAG,iBAAiB,IAAI,CAAC,YAAY,EAAE,CAAC;IACzD,OAAO,CAAC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,UAAU,CAAC;IACrD,OAAO,CAAC,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC;IAC3D,OAAO,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IACzC,OAAO,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,CAAC,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,OAAO,CAAC,CAAC;AACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PlayerMessageResolver } from "../player-message-resolver.js";
2
+ export declare function removeButton(label: string | null, messages: PlayerMessageResolver): HTMLButtonElement;
3
+ //# sourceMappingURL=remove-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-button.d.ts","sourceRoot":"","sources":["../../src/controls/remove-button.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,QAAQ,EAAE,qBAAqB,GAC9B,iBAAiB,CASnB"}
@@ -0,0 +1,12 @@
1
+ import { trashIcon } from "../icons.js";
2
+ export function removeButton(label, messages) {
3
+ const safeLabel = label?.trim() || messages.message("remove");
4
+ const button = document.createElement("button");
5
+ button.type = "button";
6
+ button.className = "qti3-icon-button qti3-remove-button";
7
+ button.title = messages.message("remove");
8
+ button.setAttribute("aria-label", messages.message("removePair", { label: safeLabel }));
9
+ button.append(trashIcon());
10
+ return button;
11
+ }
12
+ //# sourceMappingURL=remove-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-button.js","sourceRoot":"","sources":["../../src/controls/remove-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,MAAM,UAAU,YAAY,CAC1B,KAAoB,EACpB,QAA+B;IAE/B,MAAM,SAAS,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,MAAM,CAAC,SAAS,GAAG,qCAAqC,CAAC;IACzD,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IACxF,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3B,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,15 @@
1
- export type { QtiPlayerAssociationPairLabelParams, QtiPlayerMessages, QtiPlayerRemoveMessageParams, } from "./player-messages.js";
2
- export type { QtiAssessmentItemPlayerCustomEventMap, QtiAssessmentItemPlayerEvent, QtiAssessmentItemPlayerEventDetailMap, QtiAssessmentItemPlayerEventName, QtiEndAttemptEventDetail, QtiPlayerFetchXml, QtiPlayerLoadOptions, QtiPlayerMessageOverrides, QtiPlayerResolveAsset, QtiPlayerSessionControl, QtiPortableCustomMountEventDetail, QtiReadyEventDetail, QtiResponseChangeEventDetail, QtiScoreAttemptOptions, QtiScoreEventDetail, QtiStateChangeEventDetail, QtiSuspendEventDetail, QtiValidationEventDetail, } from "./player-types.js";
1
+ export type { QtiPlayerMovementDirection } from "./player-messages.js";
2
+ export type { QtiAttemptStateV1, QtiCatalogSupportResolution, QtiCatalogSupportResolutionOptions, QtiScoreResult, QtiTextToSpeechTraversal, } from "@longsightgroup/qti3-core";
3
+ export type { QtiAssessmentItemPlayerCustomEventMap, QtiAssessmentItemPlayerEvent, QtiAssessmentItemPlayerEventDetailMap, QtiAssessmentItemPlayerEventName, QtiDiagnosticsEventDetail, QtiEndAttemptEventDetail, QtiPlayerFetchXml, QtiPlayerLoadOptions, QtiPlayerResolveAsset, QtiPlayerSessionControl, QtiPortableCustomMountEventDetail, QtiReadyEventDetail, QtiResponseChangeEventDetail, QtiResetEventDetail, QtiRestoreEventDetail, QtiScoreAttemptOptions, QtiScoreEventDetail, QtiStateChangeEventDetail, QtiSuspendEventDetail, QtiValidationEventDetail, } from "./player-types.js";
4
+ export type { QtiAssessmentItemPlayerAdapterEventCallback, QtiAssessmentItemPlayerAdapterEventHandlerProps, QtiAssessmentItemPlayerAdapterEventPropName, QtiAssessmentItemPlayerAdapterLoadSyncInput, QtiAssessmentItemPlayerAdapterProps, QtiAssessmentItemPlayerAdapterPropName, QtiAssessmentItemPlayerHandle, QtiAssessmentItemPlayerLoadDependencies, } from "./player-adapter.js";
5
+ export { bindQtiAssessmentItemPlayerAdapterEvents, createQtiAssessmentItemPlayerAdapterLoadSync, createQtiAssessmentItemPlayerHandle, isQtiAssessmentItemPlayerAdapterPropName, normalizeQtiAssessmentItemPlayerLoadError, qtiAssessmentItemPlayerAdapterEventEntries, qtiAssessmentItemPlayerAdapterPropNames, qtiAssessmentItemPlayerLoadDependencies, qtiAssessmentItemPlayerLoadStateKey, syncQtiAssessmentItemPlayerAdapterChrome, syncQtiAssessmentItemPlayerAdapterMessages, } from "./player-adapter.js";
6
+ export type { PlayerMessageCatalog } from "./player-message-catalog.js";
7
+ export type { PlayerMessageKey, PlayerMessageResolverKind } from "./player-message-manifest.js";
8
+ export { PLAYER_MESSAGE_MANIFEST } from "./player-message-manifest.js";
9
+ export { createPlayerMessageResolver, defaultPlayerMessageCatalog, defaultPlayerMessageResolver, extractMessagePlaceholders, formatPlayerMessage, mergePlayerMessageCatalogs, type PlayerMessageOverride, type PlayerMessageParams, type PlayerMessageResolver, type QtiPlayerMessageOverrides, } from "./player-message-catalog.js";
10
+ export { PLAYER_MESSAGE_KEYS, PLAYER_MESSAGE_STRING_KEYS } from "./player-message-keys.js";
11
+ export type { PlayerMessageCatalogDiagnostic, PlayerMessageCatalogDiagnosticCode, PlayerMessageCatalogValidationResult, ValidatePlayerMessageCatalogOptions, } from "./player-message-catalog-validate.js";
12
+ export { allowedCatalogPlaceholders, requiredCatalogPlaceholders, validatePlayerMessageCatalog, } from "./player-message-catalog-validate.js";
13
+ export { resolvePlayerMessages } from "./player-locale.js";
3
14
  export { QtiAssessmentItemPlayer, defineQtiAssessmentItemPlayer } from "./player-element.js";
4
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mCAAmC,EACnC,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,qCAAqC,EACrC,4BAA4B,EAC5B,qCAAqC,EACrC,gCAAgC,EAChC,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,iCAAiC,EACjC,mBAAmB,EACnB,4BAA4B,EAC5B,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AACvE,YAAY,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,kCAAkC,EAClC,cAAc,EACd,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,qCAAqC,EACrC,4BAA4B,EAC5B,qCAAqC,EACrC,gCAAgC,EAChC,yBAAyB,EACzB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,iCAAiC,EACjC,mBAAmB,EACnB,4BAA4B,EAC5B,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,2CAA2C,EAC3C,+CAA+C,EAC/C,2CAA2C,EAC3C,2CAA2C,EAC3C,mCAAmC,EACnC,sCAAsC,EACtC,6BAA6B,EAC7B,uCAAuC,GACxC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,wCAAwC,EACxC,4CAA4C,EAC5C,mCAAmC,EACnC,wCAAwC,EACxC,yCAAyC,EACzC,0CAA0C,EAC1C,uCAAuC,EACvC,uCAAuC,EACvC,mCAAmC,EACnC,wCAAwC,EACxC,0CAA0C,GAC3C,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAChG,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC5B,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,GAC/B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAC3F,YAAY,EACV,8BAA8B,EAC9B,kCAAkC,EAClC,oCAAoC,EACpC,mCAAmC,GACpC,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC"}