@pie-players/pie-default-tool-loaders 0.3.68 → 0.3.70
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/README.md +38 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/packaged-capability-composition.d.ts +16 -4
- package/dist/packaged-capability-composition.js +72 -47
- package/dist/registrations/accessibility-tools.js +1 -8
- package/dist/registrations/calculator.d.ts +6 -2
- package/dist/registrations/calculator.js +104 -28
- package/dist/registrations/dictionary-tools.js +2 -2
- package/dist/registrations/interaction-tools.js +12 -2
- package/dist/registrations/measurement-tools.js +0 -2
- package/dist/registrations/overlay-toolbar-render.js +7 -0
- package/dist/registrations/subject-specific-tools.js +0 -4
- package/dist/registrations/tts.js +0 -2
- package/package.json +19 -16
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ and how does the program tier them":
|
|
|
17
17
|
| `PACKAGED_TOOL_TAG_MAP` | Which custom element each one renders as |
|
|
18
18
|
| `PACKAGED_TOOL_PLACEMENT`, `SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT`, `PACKAGED_TOOL_ORDER` | Where they appear and in what order |
|
|
19
19
|
| `UNIVERSAL_SUPPORTS_PRESET`, `createUniversalPersonalNeedsProfile` | Which of their support ids the program grants to everyone |
|
|
20
|
-
| `DEFAULT_TOOL_MODULE_LOADERS`, `registerSectionToolModuleLoaders` | When each one's bundle loads |
|
|
20
|
+
| `DEFAULT_TOOL_MODULE_LOADERS`, `createDefaultToolModuleLoaders`, `registerSectionToolModuleLoaders` | When each one's bundle loads |
|
|
21
21
|
|
|
22
22
|
The individual registrations are exported too, so a host can compose its own set
|
|
23
23
|
rather than take the packaged one whole.
|
|
@@ -52,6 +52,43 @@ const registry = createPackagedToolRegistry({
|
|
|
52
52
|
});
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
Desmos remains the calculator delivery when no provider is configured. To use
|
|
56
|
+
GeoGebra or the fully bundled open-source Cortex implementation, pass the same
|
|
57
|
+
calculator configuration to both the toolkit and the
|
|
58
|
+
packaged composition. The composition then owns the matching element tag and
|
|
59
|
+
module loader; hosts do not hand-maintain a second vendor map.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import {
|
|
63
|
+
createDefaultToolModuleLoaders,
|
|
64
|
+
createPackagedToolRegistry,
|
|
65
|
+
} from "@pie-players/pie-default-tool-loaders";
|
|
66
|
+
|
|
67
|
+
const calculatorProviderConfig = {
|
|
68
|
+
provider: {
|
|
69
|
+
id: "calculator-geogebra",
|
|
70
|
+
init: { appletTimeoutMs: 20_000 },
|
|
71
|
+
},
|
|
72
|
+
settings: { showResetIcon: true },
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const registry = createPackagedToolRegistry({
|
|
76
|
+
calculatorProviderConfig,
|
|
77
|
+
toolModuleLoaders: createDefaultToolModuleLoaders({
|
|
78
|
+
calculatorProviderConfig,
|
|
79
|
+
}),
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const tools = {
|
|
83
|
+
providers: { calculator: calculatorProviderConfig },
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
For an offline-capable calculator with no API key or runtime CDN, use
|
|
88
|
+
`provider.id: "calculator-cortex"`. Its `settings` accept angle mode, precision,
|
|
89
|
+
history, evaluation limit, allowed functions, clipboard policy, and graph
|
|
90
|
+
viewport options documented by `@pie-players/pie-calculator-cortex`.
|
|
91
|
+
|
|
55
92
|
`createDefaultToolRegistry()` in the toolkit is the other end of that choice: it
|
|
56
93
|
builds an empty registry, and a host composing its own set registers into it.
|
|
57
94
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export type { PackagedToolRegistryOptions, RegisterDefaultToolModuleLoadersOptions, RegisterPackagedToolsOptions, ToolModuleLoader, ToolRegistryLike, } from "./packaged-capability-composition.js";
|
|
2
|
-
export { createPackagedToolRegistry, createUniversalPersonalNeedsProfile, DEFAULT_TOOL_MODULE_LOADERS, ITEM_TOOL_MODULE_LOADERS, PACKAGED_TOOL_ORDER, PACKAGED_TOOL_PLACEMENT, PACKAGED_TOOL_REGISTRATIONS, PACKAGED_TOOL_TAG_MAP, registerDefaultToolModuleLoaders, registerPackagedTools, registerSectionToolModuleLoaders, SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT, SECTION_TOOL_MODULE_LOADERS, UNIVERSAL_SUPPORTS_PRESET, } from "./packaged-capability-composition.js";
|
|
1
|
+
export type { PackagedCalculatorCompositionOptions, PackagedToolRegistryOptions, RegisterDefaultToolModuleLoadersOptions, RegisterPackagedToolsOptions, ToolModuleLoader, ToolRegistryLike, } from "./packaged-capability-composition.js";
|
|
2
|
+
export { createPackagedToolRegistry, createDefaultToolModuleLoaders, createSectionToolModuleLoaders, createUniversalPersonalNeedsProfile, DEFAULT_TOOL_MODULE_LOADERS, ITEM_TOOL_MODULE_LOADERS, PACKAGED_TOOL_ORDER, PACKAGED_TOOL_PLACEMENT, PACKAGED_TOOL_REGISTRATIONS, PACKAGED_TOOL_TAG_MAP, registerDefaultToolModuleLoaders, registerPackagedTools, registerSectionToolModuleLoaders, SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT, SECTION_TOOL_MODULE_LOADERS, UNIVERSAL_SUPPORTS_PRESET, } from "./packaged-capability-composition.js";
|
|
3
3
|
export { CONTENT_ALTERNATE_REGISTRATIONS } from "./content-alternates.js";
|
|
4
4
|
export { annotationToolbarRegistration, lineReaderToolRegistration, themeToolRegistration, } from "./registrations/accessibility-tools.js";
|
|
5
5
|
export { AUDIO_TRANSCRIPT_FEATURE_ID, AUDIO_TRANSCRIPT_REGION_CLASS, AUDIO_TRANSCRIPT_REGION_LABEL, audioTranscriptRegistration, resolveAudioTranscript, type ResolvedAudioTranscript, } from "./registrations/audio-transcript.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createPackagedToolRegistry, createUniversalPersonalNeedsProfile, DEFAULT_TOOL_MODULE_LOADERS, ITEM_TOOL_MODULE_LOADERS, PACKAGED_TOOL_ORDER, PACKAGED_TOOL_PLACEMENT, PACKAGED_TOOL_REGISTRATIONS, PACKAGED_TOOL_TAG_MAP, registerDefaultToolModuleLoaders, registerPackagedTools, registerSectionToolModuleLoaders, SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT, SECTION_TOOL_MODULE_LOADERS, UNIVERSAL_SUPPORTS_PRESET, } from "./packaged-capability-composition.js";
|
|
1
|
+
export { createPackagedToolRegistry, createDefaultToolModuleLoaders, createSectionToolModuleLoaders, createUniversalPersonalNeedsProfile, DEFAULT_TOOL_MODULE_LOADERS, ITEM_TOOL_MODULE_LOADERS, PACKAGED_TOOL_ORDER, PACKAGED_TOOL_PLACEMENT, PACKAGED_TOOL_REGISTRATIONS, PACKAGED_TOOL_TAG_MAP, registerDefaultToolModuleLoaders, registerPackagedTools, registerSectionToolModuleLoaders, SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT, SECTION_TOOL_MODULE_LOADERS, UNIVERSAL_SUPPORTS_PRESET, } from "./packaged-capability-composition.js";
|
|
2
2
|
// The authored-alternate subset, for a renderer that shows alternates and no
|
|
3
3
|
// toolbar — importable without the packaged composition's tool loaders.
|
|
4
4
|
export { CONTENT_ALTERNATE_REGISTRATIONS } from "./content-alternates.js";
|
|
@@ -7,13 +7,21 @@
|
|
|
7
7
|
* Public constants are projections of this composition so adding a capability
|
|
8
8
|
* cannot leave a second hand-maintained catalogue silently behind.
|
|
9
9
|
*/
|
|
10
|
-
import { ToolRegistry, type ToolComponentFactory, type ToolComponentFactoryMap, type ToolRegistration, type ToolTagMap } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
10
|
+
import { ToolRegistry, type ToolComponentFactory, type ToolComponentFactoryMap, type ToolRegistration, type ToolTagMap, type ToolProviderConfig } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
11
11
|
import type { PersonalNeedsProfile } from "@pie-players/pie-players-shared/types";
|
|
12
12
|
export type ToolModuleLoader = () => Promise<unknown>;
|
|
13
13
|
export interface ToolRegistryLike {
|
|
14
14
|
setToolModuleLoaders(loaders: Partial<Record<string, ToolModuleLoader>>): void;
|
|
15
15
|
}
|
|
16
|
-
export interface
|
|
16
|
+
export interface PackagedCalculatorCompositionOptions {
|
|
17
|
+
/**
|
|
18
|
+
* The same calculator config supplied at `tools.providers.calculator`.
|
|
19
|
+
* Selects the matching packaged element and default loader. Omit it to retain
|
|
20
|
+
* the existing Desmos delivery.
|
|
21
|
+
*/
|
|
22
|
+
calculatorProviderConfig?: ToolProviderConfig;
|
|
23
|
+
}
|
|
24
|
+
export interface PackagedToolRegistryOptions extends PackagedCalculatorCompositionOptions {
|
|
17
25
|
/** Override packaged registrations by toolId. */
|
|
18
26
|
overrides?: Partial<Record<string, ToolRegistration>>;
|
|
19
27
|
/** Override or extend the packaged element tag mapping. */
|
|
@@ -30,9 +38,9 @@ export interface RegisterPackagedToolsOptions {
|
|
|
30
38
|
toolIds?: string[];
|
|
31
39
|
applyOverrides?: (registration: ToolRegistration) => ToolRegistration;
|
|
32
40
|
}
|
|
33
|
-
export
|
|
41
|
+
export interface RegisterDefaultToolModuleLoadersOptions extends PackagedCalculatorCompositionOptions {
|
|
34
42
|
loaders?: Partial<Record<string, ToolModuleLoader>>;
|
|
35
|
-
}
|
|
43
|
+
}
|
|
36
44
|
/**
|
|
37
45
|
* Release/build gate for PIE-authored composition data.
|
|
38
46
|
*
|
|
@@ -46,6 +54,10 @@ export declare const PACKAGED_TOOL_TAG_MAP: ToolTagMap;
|
|
|
46
54
|
export declare const ITEM_TOOL_MODULE_LOADERS: Record<string, ToolModuleLoader>;
|
|
47
55
|
export declare const SECTION_TOOL_MODULE_LOADERS: Record<string, ToolModuleLoader>;
|
|
48
56
|
export declare const DEFAULT_TOOL_MODULE_LOADERS: Record<string, ToolModuleLoader>;
|
|
57
|
+
/** Build the packaged loader map for a selected calculator provider. */
|
|
58
|
+
export declare function createDefaultToolModuleLoaders(options?: PackagedCalculatorCompositionOptions): Record<string, ToolModuleLoader>;
|
|
59
|
+
/** Build the section-bootstrap loader subset for a selected calculator provider. */
|
|
60
|
+
export declare function createSectionToolModuleLoaders(options?: PackagedCalculatorCompositionOptions): Record<string, ToolModuleLoader>;
|
|
49
61
|
export declare const PACKAGED_TOOL_PLACEMENT: {
|
|
50
62
|
readonly assessment: readonly ["theme"];
|
|
51
63
|
readonly section: readonly ["theme"];
|
|
@@ -10,20 +10,40 @@
|
|
|
10
10
|
import { ToolRegistry, } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
11
11
|
import { annotationToolbarRegistration, lineReaderToolRegistration, themeToolRegistration, } from "./registrations/accessibility-tools.js";
|
|
12
12
|
import { audioTranscriptRegistration } from "./registrations/audio-transcript.js";
|
|
13
|
-
import { calculatorToolRegistration } from "./registrations/calculator.js";
|
|
13
|
+
import { calculatorToolRegistration, resolveCalculatorProviderId, } from "./registrations/calculator.js";
|
|
14
14
|
import { dictionaryToolRegistration, pictureDictionaryToolRegistration, spanishDictionaryToolRegistration, spanishPictureDictionaryToolRegistration, } from "./registrations/dictionary-tools.js";
|
|
15
15
|
import { answerEliminatorToolRegistration } from "./registrations/interaction-tools.js";
|
|
16
16
|
import { protractorToolRegistration, rulerToolRegistration, } from "./registrations/measurement-tools.js";
|
|
17
17
|
import { graphToolRegistration, periodicTableToolRegistration, } from "./registrations/subject-specific-tools.js";
|
|
18
18
|
import { ttsToolRegistration } from "./registrations/tts.js";
|
|
19
19
|
const loadSideEffectModule = (load) => load().then(() => undefined);
|
|
20
|
-
function
|
|
20
|
+
function loadCalculatorElement(tagName, load) {
|
|
21
21
|
if (typeof globalThis !== "undefined" &&
|
|
22
22
|
"customElements" in globalThis &&
|
|
23
|
-
globalThis.customElements?.get(
|
|
23
|
+
globalThis.customElements?.get(tagName)) {
|
|
24
24
|
return Promise.resolve();
|
|
25
25
|
}
|
|
26
|
-
return loadSideEffectModule(
|
|
26
|
+
return loadSideEffectModule(load);
|
|
27
|
+
}
|
|
28
|
+
const loadDesmosCalculatorModule = () => loadCalculatorElement("pie-tool-calculator", () => import("@pie-players/pie-tool-calculator-shared/calculator-element"));
|
|
29
|
+
const loadGeoGebraCalculatorModule = () => loadCalculatorElement("pie-tool-calculator-geogebra", () => import("@pie-players/pie-tool-calculator-geogebra"));
|
|
30
|
+
const loadCortexCalculatorModule = () => loadCalculatorElement("pie-tool-calculator-cortex", () => import("@pie-players/pie-tool-calculator-cortex"));
|
|
31
|
+
const CALCULATOR_DELIVERY = {
|
|
32
|
+
"calculator-desmos": {
|
|
33
|
+
tagName: "pie-tool-calculator",
|
|
34
|
+
loadModule: loadDesmosCalculatorModule,
|
|
35
|
+
},
|
|
36
|
+
"calculator-geogebra": {
|
|
37
|
+
tagName: "pie-tool-calculator-geogebra",
|
|
38
|
+
loadModule: loadGeoGebraCalculatorModule,
|
|
39
|
+
},
|
|
40
|
+
"calculator-cortex": {
|
|
41
|
+
tagName: "pie-tool-calculator-cortex",
|
|
42
|
+
loadModule: loadCortexCalculatorModule,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
function resolveCalculatorDelivery(config) {
|
|
46
|
+
return CALCULATOR_DELIVERY[resolveCalculatorProviderId(config)];
|
|
27
47
|
}
|
|
28
48
|
const loadTtsModule = () => loadSideEffectModule(() => import("@pie-players/pie-tool-tts-inline"));
|
|
29
49
|
const loadRulerModule = () => loadSideEffectModule(() => import("@pie-players/pie-tool-ruler"));
|
|
@@ -39,18 +59,13 @@ const loadPictureDictionaryModule = () => loadSideEffectModule(() => import("@pi
|
|
|
39
59
|
const PACKAGED_CAPABILITY_DEFINITIONS = [
|
|
40
60
|
{
|
|
41
61
|
registration: calculatorToolRegistration,
|
|
42
|
-
tagName: "
|
|
43
|
-
loadModule:
|
|
62
|
+
tagName: CALCULATOR_DELIVERY["calculator-desmos"].tagName,
|
|
63
|
+
loadModule: CALCULATOR_DELIVERY["calculator-desmos"].loadModule,
|
|
44
64
|
loaderTargets: ["item", "section"],
|
|
45
65
|
placementOrder: { element: 10 },
|
|
46
66
|
preferredPlacementOrder: { item: 10 },
|
|
47
67
|
toolbarOrder: 20,
|
|
48
|
-
universalSupportIds: [
|
|
49
|
-
"calculator",
|
|
50
|
-
"graphingCalculator",
|
|
51
|
-
"basicCalculator",
|
|
52
|
-
"scientificCalculator",
|
|
53
|
-
],
|
|
68
|
+
universalSupportIds: ["calculator", "graphingCalculator"],
|
|
54
69
|
},
|
|
55
70
|
{
|
|
56
71
|
registration: ttsToolRegistration,
|
|
@@ -60,7 +75,7 @@ const PACKAGED_CAPABILITY_DEFINITIONS = [
|
|
|
60
75
|
placementOrder: { item: 10, passage: 10, rubric: 10, element: 30 },
|
|
61
76
|
preferredPlacementOrder: { item: 20, passage: 10 },
|
|
62
77
|
toolbarOrder: 30,
|
|
63
|
-
universalSupportIds: ["textToSpeech", "readAloud"
|
|
78
|
+
universalSupportIds: ["textToSpeech", "readAloud"],
|
|
64
79
|
},
|
|
65
80
|
{
|
|
66
81
|
registration: rulerToolRegistration,
|
|
@@ -70,7 +85,7 @@ const PACKAGED_CAPABILITY_DEFINITIONS = [
|
|
|
70
85
|
placementOrder: { element: 40 },
|
|
71
86
|
preferredPlacementOrder: { section: 50 },
|
|
72
87
|
toolbarOrder: 80,
|
|
73
|
-
universalSupportIds: ["ruler"
|
|
88
|
+
universalSupportIds: ["ruler"],
|
|
74
89
|
},
|
|
75
90
|
{
|
|
76
91
|
registration: protractorToolRegistration,
|
|
@@ -80,7 +95,7 @@ const PACKAGED_CAPABILITY_DEFINITIONS = [
|
|
|
80
95
|
placementOrder: { element: 50 },
|
|
81
96
|
preferredPlacementOrder: { section: 60 },
|
|
82
97
|
toolbarOrder: 90,
|
|
83
|
-
universalSupportIds: ["protractor"
|
|
98
|
+
universalSupportIds: ["protractor"],
|
|
84
99
|
},
|
|
85
100
|
{
|
|
86
101
|
registration: answerEliminatorToolRegistration,
|
|
@@ -90,12 +105,7 @@ const PACKAGED_CAPABILITY_DEFINITIONS = [
|
|
|
90
105
|
placementOrder: { element: 20 },
|
|
91
106
|
preferredPlacementOrder: { item: 30 },
|
|
92
107
|
toolbarOrder: 70,
|
|
93
|
-
universalSupportIds: [
|
|
94
|
-
"answerMasking",
|
|
95
|
-
"answerEliminator",
|
|
96
|
-
"strikethrough",
|
|
97
|
-
"choiceMasking",
|
|
98
|
-
],
|
|
108
|
+
universalSupportIds: ["answerMasking", "answerEliminator", "strikethrough"],
|
|
99
109
|
},
|
|
100
110
|
{
|
|
101
111
|
registration: lineReaderToolRegistration,
|
|
@@ -105,13 +115,7 @@ const PACKAGED_CAPABILITY_DEFINITIONS = [
|
|
|
105
115
|
placementOrder: { passage: 40, rubric: 40 },
|
|
106
116
|
preferredPlacementOrder: { section: 40 },
|
|
107
117
|
toolbarOrder: 40,
|
|
108
|
-
universalSupportIds: [
|
|
109
|
-
"readingMask",
|
|
110
|
-
"readingGuide",
|
|
111
|
-
"readingRuler",
|
|
112
|
-
"lineReader",
|
|
113
|
-
"trackingGuide",
|
|
114
|
-
],
|
|
118
|
+
universalSupportIds: ["readingMask", "readingGuide", "readingRuler"],
|
|
115
119
|
},
|
|
116
120
|
{
|
|
117
121
|
registration: themeToolRegistration,
|
|
@@ -126,8 +130,6 @@ const PACKAGED_CAPABILITY_DEFINITIONS = [
|
|
|
126
130
|
"colorContrast",
|
|
127
131
|
"invertColors",
|
|
128
132
|
"theme",
|
|
129
|
-
"highContrast",
|
|
130
|
-
"customColors",
|
|
131
133
|
],
|
|
132
134
|
},
|
|
133
135
|
{
|
|
@@ -141,13 +143,7 @@ const PACKAGED_CAPABILITY_DEFINITIONS = [
|
|
|
141
143
|
// The last three came from the `highlighter` capability, which mounted this
|
|
142
144
|
// same element behind a second identically-labelled button. Kept here so a
|
|
143
145
|
// profile granted one of the older ids still gets highlighting.
|
|
144
|
-
universalSupportIds: [
|
|
145
|
-
"highlighting",
|
|
146
|
-
"annotations",
|
|
147
|
-
"highlighter",
|
|
148
|
-
"textHighlight",
|
|
149
|
-
"annotation",
|
|
150
|
-
],
|
|
146
|
+
universalSupportIds: ["highlighting", "annotations"],
|
|
151
147
|
},
|
|
152
148
|
{
|
|
153
149
|
registration: graphToolRegistration,
|
|
@@ -157,7 +153,7 @@ const PACKAGED_CAPABILITY_DEFINITIONS = [
|
|
|
157
153
|
placementOrder: { item: 40, element: 80 },
|
|
158
154
|
preferredPlacementOrder: { section: 20 },
|
|
159
155
|
toolbarOrder: 100,
|
|
160
|
-
universalSupportIds: ["graph"
|
|
156
|
+
universalSupportIds: ["graph"],
|
|
161
157
|
},
|
|
162
158
|
{
|
|
163
159
|
registration: periodicTableToolRegistration,
|
|
@@ -167,11 +163,7 @@ const PACKAGED_CAPABILITY_DEFINITIONS = [
|
|
|
167
163
|
placementOrder: { item: 50, element: 90 },
|
|
168
164
|
preferredPlacementOrder: { section: 30 },
|
|
169
165
|
toolbarOrder: 110,
|
|
170
|
-
universalSupportIds: [
|
|
171
|
-
"periodicTable",
|
|
172
|
-
"chemistryReference",
|
|
173
|
-
"elementReference",
|
|
174
|
-
],
|
|
166
|
+
universalSupportIds: ["periodicTable"],
|
|
175
167
|
},
|
|
176
168
|
{
|
|
177
169
|
registration: dictionaryToolRegistration,
|
|
@@ -406,10 +398,27 @@ class PackagedCapabilityComposition {
|
|
|
406
398
|
// their bundle/runtime behavior.
|
|
407
399
|
if (options.toolModuleLoaders &&
|
|
408
400
|
Object.keys(options.toolModuleLoaders).length > 0) {
|
|
409
|
-
|
|
401
|
+
const toolModuleLoaders = { ...options.toolModuleLoaders };
|
|
402
|
+
const calculatorDelivery = resolveCalculatorDelivery(options.calculatorProviderConfig);
|
|
403
|
+
// A host using the packaged default map gets a coherent provider-specific
|
|
404
|
+
// loader. A genuinely custom calculator loader remains the host's override.
|
|
405
|
+
if (options.calculatorProviderConfig &&
|
|
406
|
+
toolModuleLoaders.calculator === this.defaultModuleLoaders.calculator) {
|
|
407
|
+
toolModuleLoaders.calculator = calculatorDelivery.loadModule;
|
|
408
|
+
}
|
|
409
|
+
registry.setToolModuleLoaders(toolModuleLoaders);
|
|
410
410
|
}
|
|
411
|
+
const calculatorTagMap = options.calculatorProviderConfig
|
|
412
|
+
? {
|
|
413
|
+
calculator: resolveCalculatorDelivery(options.calculatorProviderConfig).tagName,
|
|
414
|
+
}
|
|
415
|
+
: {};
|
|
411
416
|
registry.setComponentOverrides({
|
|
412
|
-
toolTagMap: {
|
|
417
|
+
toolTagMap: {
|
|
418
|
+
...this.toolTagMap,
|
|
419
|
+
...calculatorTagMap,
|
|
420
|
+
...(options.toolTagMap ?? {}),
|
|
421
|
+
},
|
|
413
422
|
toolComponentFactory: options.toolComponentFactory,
|
|
414
423
|
toolComponentFactories: options.toolComponentFactories,
|
|
415
424
|
});
|
|
@@ -450,6 +459,22 @@ export const SECTION_TOOL_MODULE_LOADERS = {
|
|
|
450
459
|
export const DEFAULT_TOOL_MODULE_LOADERS = {
|
|
451
460
|
...packagedCapabilityComposition.defaultModuleLoaders,
|
|
452
461
|
};
|
|
462
|
+
/** Build the packaged loader map for a selected calculator provider. */
|
|
463
|
+
export function createDefaultToolModuleLoaders(options = {}) {
|
|
464
|
+
return {
|
|
465
|
+
...DEFAULT_TOOL_MODULE_LOADERS,
|
|
466
|
+
calculator: resolveCalculatorDelivery(options.calculatorProviderConfig)
|
|
467
|
+
.loadModule,
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
/** Build the section-bootstrap loader subset for a selected calculator provider. */
|
|
471
|
+
export function createSectionToolModuleLoaders(options = {}) {
|
|
472
|
+
return {
|
|
473
|
+
...SECTION_TOOL_MODULE_LOADERS,
|
|
474
|
+
calculator: resolveCalculatorDelivery(options.calculatorProviderConfig)
|
|
475
|
+
.loadModule,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
453
478
|
export const PACKAGED_TOOL_PLACEMENT = {
|
|
454
479
|
assessment: [...packagedCapabilityComposition.placement.assessment],
|
|
455
480
|
section: [...packagedCapabilityComposition.placement.section],
|
|
@@ -482,14 +507,14 @@ export function createUniversalPersonalNeedsProfile() {
|
|
|
482
507
|
/** Register packaged lazy module loaders, followed by host overrides. */
|
|
483
508
|
export function registerDefaultToolModuleLoaders(registry, options = {}) {
|
|
484
509
|
registry.setToolModuleLoaders({
|
|
485
|
-
...
|
|
510
|
+
...createDefaultToolModuleLoaders(options),
|
|
486
511
|
...(options.loaders ?? {}),
|
|
487
512
|
});
|
|
488
513
|
}
|
|
489
514
|
/** Register only the section-bootstrap loader subset, then host overrides. */
|
|
490
515
|
export function registerSectionToolModuleLoaders(registry, options = {}) {
|
|
491
516
|
registry.setToolModuleLoaders({
|
|
492
|
-
...
|
|
517
|
+
...createSectionToolModuleLoaders(options),
|
|
493
518
|
...(options.loaders ?? {}),
|
|
494
519
|
});
|
|
495
520
|
}
|
|
@@ -36,8 +36,6 @@ export const lineReaderToolRegistration = {
|
|
|
36
36
|
"readingMask", // QTI 3.0 standard (reading.readingMask)
|
|
37
37
|
"readingGuide", // QTI 3.0 standard (reading.readingGuide)
|
|
38
38
|
"readingRuler", // QTI 3.0 standard (reading.readingRuler)
|
|
39
|
-
"lineReader", // Common variant
|
|
40
|
-
"trackingGuide", // Common variant
|
|
41
39
|
],
|
|
42
40
|
/**
|
|
43
41
|
* Pass 2: Line reader is relevant when readable text is present
|
|
@@ -73,9 +71,7 @@ export const themeToolRegistration = {
|
|
|
73
71
|
"highContrastDisplay", // QTI 3.0 standard (visual.highContrastDisplay)
|
|
74
72
|
"colorContrast", // QTI 3.0 standard (visual.colorContrast)
|
|
75
73
|
"invertColors", // QTI 3.0 standard (visual.invertColors)
|
|
76
|
-
"theme", // Canonical id
|
|
77
|
-
"highContrast", // Common variant
|
|
78
|
-
"customColors", // Common variant
|
|
74
|
+
"theme", // Canonical id, and this registration's toolId
|
|
79
75
|
],
|
|
80
76
|
/**
|
|
81
77
|
* Pass 2: Color scheme is always relevant when allowed
|
|
@@ -127,9 +123,6 @@ export const annotationToolbarRegistration = {
|
|
|
127
123
|
pnpSupportIds: [
|
|
128
124
|
"highlighting", // QTI 3.0 standard (cognitive.highlighting / reading.wordHighlighting)
|
|
129
125
|
"annotations", // QTI 3.0 standard (cognitive.annotations)
|
|
130
|
-
"highlighter", // Common variant
|
|
131
|
-
"textHighlight", // Common variant
|
|
132
|
-
"annotation", // Common variant
|
|
133
126
|
],
|
|
134
127
|
/**
|
|
135
128
|
* Pass 2: Annotation is relevant when readable text is present
|
|
@@ -2,18 +2,22 @@
|
|
|
2
2
|
* Calculator Tool Registration
|
|
3
3
|
*
|
|
4
4
|
* Registers the calculator tool with support for multiple calculator types
|
|
5
|
-
* (basic, scientific, graphing)
|
|
5
|
+
* (basic, scientific, graphing) through a host-selected provider.
|
|
6
6
|
*
|
|
7
7
|
* Maps to QTI 3.0 standard access features:
|
|
8
8
|
* - calculator (cognitive support)
|
|
9
9
|
* - graphingCalculator (assessment tool)
|
|
10
10
|
*/
|
|
11
11
|
import type { ToolRegistration } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
12
|
+
import type { ToolProviderConfig } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
13
|
+
export type CalculatorProviderId = "calculator-desmos" | "calculator-geogebra" | "calculator-cortex";
|
|
14
|
+
export declare const DEFAULT_CALCULATOR_PROVIDER_ID: CalculatorProviderId;
|
|
15
|
+
export declare function resolveCalculatorProviderId(config: ToolProviderConfig | undefined): CalculatorProviderId;
|
|
12
16
|
/**
|
|
13
17
|
* Calculator tool registration
|
|
14
18
|
*
|
|
15
19
|
* Supports:
|
|
16
|
-
* - Basic, scientific, and graphing calculators
|
|
20
|
+
* - Basic, scientific, and graphing calculators through Desmos, GeoGebra, or Cortex
|
|
17
21
|
* - Context-aware visibility (shows only when math content is detected)
|
|
18
22
|
* - Item level only
|
|
19
23
|
*/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Calculator Tool Registration
|
|
3
3
|
*
|
|
4
4
|
* Registers the calculator tool with support for multiple calculator types
|
|
5
|
-
* (basic, scientific, graphing)
|
|
5
|
+
* (basic, scientific, graphing) through a host-selected provider.
|
|
6
6
|
*
|
|
7
7
|
* Maps to QTI 3.0 standard access features:
|
|
8
8
|
* - calculator (cognitive support)
|
|
@@ -11,7 +11,45 @@
|
|
|
11
11
|
import { hasMathContent } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
12
12
|
import { createScopedToolId } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
13
13
|
import { DesmosToolProvider } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
14
|
+
import { CortexToolProvider } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
15
|
+
import { GeoGebraToolProvider } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
14
16
|
import { createToolElement } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
17
|
+
export const DEFAULT_CALCULATOR_PROVIDER_ID = "calculator-desmos";
|
|
18
|
+
export function resolveCalculatorProviderId(config) {
|
|
19
|
+
const configured = config?.provider?.id;
|
|
20
|
+
if (configured === undefined || configured === "") {
|
|
21
|
+
return DEFAULT_CALCULATOR_PROVIDER_ID;
|
|
22
|
+
}
|
|
23
|
+
if (configured === "calculator-desmos" ||
|
|
24
|
+
configured === "calculator-geogebra" ||
|
|
25
|
+
configured === "calculator-cortex") {
|
|
26
|
+
return configured;
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`Unsupported calculator provider "${String(configured)}". Expected "calculator-desmos", "calculator-geogebra", or "calculator-cortex".`);
|
|
29
|
+
}
|
|
30
|
+
function createCalculatorToolProvider(config) {
|
|
31
|
+
switch (resolveCalculatorProviderId(config)) {
|
|
32
|
+
case "calculator-cortex":
|
|
33
|
+
return new CortexToolProvider();
|
|
34
|
+
case "calculator-geogebra":
|
|
35
|
+
return new GeoGebraToolProvider();
|
|
36
|
+
default:
|
|
37
|
+
return new DesmosToolProvider();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function getCalculatorInstanceConfig(config) {
|
|
41
|
+
const theme = config?.theme;
|
|
42
|
+
return {
|
|
43
|
+
settings: config?.settings && typeof config.settings === "object"
|
|
44
|
+
? { ...config.settings }
|
|
45
|
+
: {},
|
|
46
|
+
restrictedMode: config?.restrictedMode === true,
|
|
47
|
+
locale: typeof config?.locale === "string" ? config.locale : undefined,
|
|
48
|
+
theme: theme === "light" || theme === "dark" || theme === "auto"
|
|
49
|
+
? theme
|
|
50
|
+
: undefined,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
15
53
|
// The toolbar parent re-derives `renderedTools` whenever item state changes
|
|
16
54
|
// (e.g. the learner answers a question and `effectiveItem`/`renderContext`
|
|
17
55
|
// recompute). Calculator initialization is expensive (Desmos boot, container
|
|
@@ -45,7 +83,9 @@ function setCachedOverlay(coordinator, fullToolId, element) {
|
|
|
45
83
|
scoped.set(fullToolId, element);
|
|
46
84
|
}
|
|
47
85
|
function normalizeCalculatorType(value) {
|
|
48
|
-
return value === "basic" || value === "scientific"
|
|
86
|
+
return value === "basic" || value === "scientific" || value === "graphing"
|
|
87
|
+
? value
|
|
88
|
+
: null;
|
|
49
89
|
}
|
|
50
90
|
function getCalculatorRenderParams(toolbarContext) {
|
|
51
91
|
const params = toolbarContext.getToolRenderParams?.("calculator") ?? {};
|
|
@@ -74,10 +114,14 @@ function getCalculatorRenderParams(toolbarContext) {
|
|
|
74
114
|
const CALCULATOR_NAME_KEYS = {
|
|
75
115
|
basic: "tools.calculator.nameBasic",
|
|
76
116
|
scientific: "tools.calculator.nameScientific",
|
|
117
|
+
graphing: "tools.calculator.nameGraphing",
|
|
77
118
|
untyped: "tools.calculator.name",
|
|
78
119
|
};
|
|
79
|
-
function applyCalculatorParamsToElement(element, calculatorType, availableTypes) {
|
|
120
|
+
function applyCalculatorParamsToElement(element, calculatorType, availableTypes, providerId, calculatorConfig) {
|
|
80
121
|
const calculatorElement = element;
|
|
122
|
+
calculatorElement.providerId = providerId;
|
|
123
|
+
calculatorElement.calculatorConfig = calculatorConfig;
|
|
124
|
+
element.setAttribute("provider-id", providerId);
|
|
81
125
|
if (calculatorType) {
|
|
82
126
|
calculatorElement.calculatorType = calculatorType;
|
|
83
127
|
element.setAttribute("calculator-type", calculatorType);
|
|
@@ -97,7 +141,7 @@ function applyCalculatorParamsToElement(element, calculatorType, availableTypes)
|
|
|
97
141
|
* Calculator tool registration
|
|
98
142
|
*
|
|
99
143
|
* Supports:
|
|
100
|
-
* - Basic, scientific, and graphing calculators
|
|
144
|
+
* - Basic, scientific, and graphing calculators through Desmos, GeoGebra, or Cortex
|
|
101
145
|
* - Context-aware visibility (shows only when math content is detected)
|
|
102
146
|
* - Item level only
|
|
103
147
|
*/
|
|
@@ -109,25 +153,14 @@ export const calculatorToolRegistration = {
|
|
|
109
153
|
descriptionKey: "tools.calculator.description",
|
|
110
154
|
icon: "calculator",
|
|
111
155
|
provider: {
|
|
112
|
-
getProviderId:
|
|
113
|
-
|
|
114
|
-
: "calculator-desmos",
|
|
115
|
-
createProvider: () => new DesmosToolProvider(),
|
|
156
|
+
getProviderId: resolveCalculatorProviderId,
|
|
157
|
+
createProvider: createCalculatorToolProvider,
|
|
116
158
|
getInitConfig: (config) => config?.provider?.init ?? {},
|
|
117
159
|
getAuthFetcher: (config) => {
|
|
118
160
|
const runtimeAuthFetcher = config?.provider?.runtime?.authFetcher;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const response = await fetch("/api/tools/desmos/auth", {
|
|
123
|
-
method: "GET",
|
|
124
|
-
credentials: "same-origin",
|
|
125
|
-
});
|
|
126
|
-
if (!response.ok) {
|
|
127
|
-
throw new Error(`Failed to fetch Desmos auth config (${response.status})`);
|
|
128
|
-
}
|
|
129
|
-
return (await response.json());
|
|
130
|
-
};
|
|
161
|
+
return typeof runtimeAuthFetcher === "function"
|
|
162
|
+
? runtimeAuthFetcher
|
|
163
|
+
: undefined;
|
|
131
164
|
},
|
|
132
165
|
lazy: true,
|
|
133
166
|
},
|
|
@@ -135,11 +168,13 @@ export const calculatorToolRegistration = {
|
|
|
135
168
|
supportedLevels: ["item"],
|
|
136
169
|
// PNP support IDs that enable this tool
|
|
137
170
|
// Maps to QTI 3.0 standard features: calculator, graphingCalculator
|
|
171
|
+
// A type is not a feature id: `calculatorType` arrives through the host's
|
|
172
|
+
// render params, so `basicCalculator` / `scientificCalculator` granted the
|
|
173
|
+
// same untyped calculator these two do and only looked like they selected a
|
|
174
|
+
// variant.
|
|
138
175
|
pnpSupportIds: [
|
|
139
176
|
"calculator", // QTI 3.0 standard (cognitive.calculator)
|
|
140
177
|
"graphingCalculator", // QTI 3.0 standard (assessment.graphingCalculator)
|
|
141
|
-
"basicCalculator", // Common variant
|
|
142
|
-
"scientificCalculator", // Common variant
|
|
143
178
|
],
|
|
144
179
|
/**
|
|
145
180
|
* Pass 2: Determine if calculator is relevant in this context
|
|
@@ -153,6 +188,9 @@ export const calculatorToolRegistration = {
|
|
|
153
188
|
},
|
|
154
189
|
renderToolbar(context, toolbarContext) {
|
|
155
190
|
const { calculatorType, availableTypes, displayName } = getCalculatorRenderParams(toolbarContext);
|
|
191
|
+
const calculatorToolConfig = toolbarContext.toolkitCoordinator?.config.tools?.providers?.calculator;
|
|
192
|
+
const providerId = resolveCalculatorProviderId(calculatorToolConfig);
|
|
193
|
+
const calculatorConfig = getCalculatorInstanceConfig(calculatorToolConfig);
|
|
156
194
|
const fullToolId = createScopedToolId(this.toolId, toolbarContext.scope.level, toolbarContext.scope.scopeId);
|
|
157
195
|
const componentOverrides = toolbarContext.componentOverrides;
|
|
158
196
|
const cachedOverlay = getCachedOverlay(toolbarContext.toolCoordinator, fullToolId);
|
|
@@ -163,7 +201,7 @@ export const calculatorToolRegistration = {
|
|
|
163
201
|
}
|
|
164
202
|
overlay.setAttribute("tool-id", fullToolId);
|
|
165
203
|
overlay.toolkitCoordinator = toolbarContext.toolkitCoordinator;
|
|
166
|
-
applyCalculatorParamsToElement(overlay, calculatorType, availableTypes);
|
|
204
|
+
applyCalculatorParamsToElement(overlay, calculatorType, availableTypes, providerId, calculatorConfig);
|
|
167
205
|
const button = {
|
|
168
206
|
toolId: this.toolId,
|
|
169
207
|
label: displayName,
|
|
@@ -199,11 +237,49 @@ export const calculatorToolRegistration = {
|
|
|
199
237
|
draggable: true,
|
|
200
238
|
resizable: true,
|
|
201
239
|
closeable: true,
|
|
202
|
-
|
|
203
|
-
|
|
240
|
+
/*
|
|
241
|
+
* Sized per type from what each layout measures, rather than one
|
|
242
|
+
* size for all three. A shell subtracts ~74px of header from the
|
|
243
|
+
* height it is given, and the numbers below are the content each
|
|
244
|
+
* type needs plus room for its history tape:
|
|
245
|
+
*
|
|
246
|
+
* - basic: strip, display, edit row and a four-row keypad measure
|
|
247
|
+
* 398px. 560 left ~90px of blank above the entry line, which is
|
|
248
|
+
* the gap that made the panel look mis-sized.
|
|
249
|
+
* - scientific: the same plus a keypad layer tab row.
|
|
250
|
+
* - graphing: the expression rail beside the plot, whose column
|
|
251
|
+
* wants 486px on its own — viewport controls, a 14rem board floor
|
|
252
|
+
* and the readout that *is* the graph for assistive technology,
|
|
253
|
+
* since the board itself is `aria-hidden`. At 620 that column was
|
|
254
|
+
* 12px short and the readout's last line was cut off.
|
|
255
|
+
*
|
|
256
|
+
* The minimums stay shared across types and providers. This
|
|
257
|
+
* registration serves Desmos, GeoGebra and Cortex alike, so a
|
|
258
|
+
* graphing-only floor would move the resize limit under two vendors
|
|
259
|
+
* whose layouts were never measured for it. Cortex below 42rem
|
|
260
|
+
* stacks the rail above the plot and needs 701px there, which no
|
|
261
|
+
* spacing tier closes — it scrolls its own content instead of
|
|
262
|
+
* clipping it, which is the contract every size below the opening
|
|
263
|
+
* one already relies on.
|
|
264
|
+
*/
|
|
265
|
+
initialWidth: calculatorType === "graphing" ? 720 : 380,
|
|
266
|
+
initialHeight: calculatorType === "graphing"
|
|
267
|
+
? 660
|
|
268
|
+
: calculatorType === "basic"
|
|
269
|
+
? 500
|
|
270
|
+
: 560,
|
|
204
271
|
minWidth: 380,
|
|
205
|
-
minHeight:
|
|
206
|
-
|
|
272
|
+
minHeight: 480,
|
|
273
|
+
/*
|
|
274
|
+
* `bottom-right` put a 560-620px-tall shell over the items
|
|
275
|
+
* column it shares the viewport with — tall enough, at
|
|
276
|
+
* ordinary viewport heights, to sit on top of a sibling
|
|
277
|
+
* item's own toolbar row and block its button from mouse
|
|
278
|
+
* and touch input. `bottom-left` keeps the same footprint
|
|
279
|
+
* over the passage column instead, which carries no
|
|
280
|
+
* per-item controls to collide with.
|
|
281
|
+
*/
|
|
282
|
+
initialAlign: "bottom-left",
|
|
207
283
|
initialMargin: 16,
|
|
208
284
|
// Header controls in the host's design system, and the layout that
|
|
209
285
|
// goes with them.
|
|
@@ -237,7 +313,7 @@ export const calculatorToolRegistration = {
|
|
|
237
313
|
if (overlay.toolkitCoordinator !== toolbarContext.toolkitCoordinator) {
|
|
238
314
|
overlay.toolkitCoordinator = toolbarContext.toolkitCoordinator;
|
|
239
315
|
}
|
|
240
|
-
applyCalculatorParamsToElement(overlay, calculatorType, availableTypes);
|
|
316
|
+
applyCalculatorParamsToElement(overlay, calculatorType, availableTypes, providerId, calculatorConfig);
|
|
241
317
|
},
|
|
242
318
|
subscribeActive: (callback) => {
|
|
243
319
|
if (!toolbarContext.subscribeVisibility)
|
|
@@ -223,13 +223,13 @@ export const spanishDictionaryToolRegistration = createDictionaryToolRegistratio
|
|
|
223
223
|
toolId: "dictionarySpanish",
|
|
224
224
|
name: "Spanish Dictionary",
|
|
225
225
|
description: "Look up word definitions in Spanish",
|
|
226
|
-
pnpSupportIds: ["spanishDictionary"
|
|
226
|
+
pnpSupportIds: ["spanishDictionary"],
|
|
227
227
|
lookupLanguage: "es",
|
|
228
228
|
});
|
|
229
229
|
export const spanishPictureDictionaryToolRegistration = createPictureDictionaryToolRegistration({
|
|
230
230
|
toolId: "pictureDictionarySpanish",
|
|
231
231
|
name: "Spanish Picture Dictionary",
|
|
232
232
|
description: "Look up pictures for words in Spanish",
|
|
233
|
-
pnpSupportIds: ["spanishPictureDictionary"
|
|
233
|
+
pnpSupportIds: ["spanishPictureDictionary"],
|
|
234
234
|
lookupLanguage: "es",
|
|
235
235
|
});
|
|
@@ -33,8 +33,7 @@ export const answerEliminatorToolRegistration = {
|
|
|
33
33
|
pnpSupportIds: [
|
|
34
34
|
"answerMasking", // QTI 3.0 standard (assessment.answerMasking)
|
|
35
35
|
"answerEliminator", // QTI 3.0 standard (assessment.answerEliminator)
|
|
36
|
-
"strikethrough", //
|
|
37
|
-
"choiceMasking", // Common variant
|
|
36
|
+
"strikethrough", // QTI 3.0 standard (assessment.strikethrough)
|
|
38
37
|
],
|
|
39
38
|
/**
|
|
40
39
|
* Pass 2: Answer eliminator is relevant only for choice-based questions
|
|
@@ -42,6 +41,17 @@ export const answerEliminatorToolRegistration = {
|
|
|
42
41
|
isVisibleInContext(context) {
|
|
43
42
|
return hasChoiceInteraction(context);
|
|
44
43
|
},
|
|
44
|
+
/**
|
|
45
|
+
* Pass 3: the same question, asked as a capability. Elimination controls are
|
|
46
|
+
* rendered per choice, so an item with no choice interaction gives this tool
|
|
47
|
+
* nothing to act on — `placement-ordering`, `categorize` and
|
|
48
|
+
* `drag-in-the-blank` included, whose `choices` hold draggables the
|
|
49
|
+
* eliminator cannot reach. Answering the relevance gate alone left the button
|
|
50
|
+
* on those items for any learner whose profile grants answer masking.
|
|
51
|
+
*/
|
|
52
|
+
isApplicableToContent(context) {
|
|
53
|
+
return hasChoiceInteraction(context);
|
|
54
|
+
},
|
|
45
55
|
renderToolbar(context, toolbarContext) {
|
|
46
56
|
const visibility = createScopedVisibilityBinding(this.toolId, toolbarContext);
|
|
47
57
|
const componentOverrides = toolbarContext.componentOverrides ?? {};
|
|
@@ -30,7 +30,6 @@ export const rulerToolRegistration = {
|
|
|
30
30
|
// Maps to QTI 3.0 standard feature: ruler
|
|
31
31
|
pnpSupportIds: [
|
|
32
32
|
"ruler", // QTI 3.0 standard (assessment.ruler)
|
|
33
|
-
"measurement", // Common variant
|
|
34
33
|
],
|
|
35
34
|
/**
|
|
36
35
|
* Pass 2: Ruler is relevant when math content is present
|
|
@@ -64,7 +63,6 @@ export const protractorToolRegistration = {
|
|
|
64
63
|
// Maps to QTI 3.0 standard feature: protractor
|
|
65
64
|
pnpSupportIds: [
|
|
66
65
|
"protractor", // QTI 3.0 standard (assessment.protractor)
|
|
67
|
-
"angleMeasurement", // Common variant
|
|
68
66
|
],
|
|
69
67
|
/**
|
|
70
68
|
* Pass 2: Protractor is relevant when math content is present
|
|
@@ -46,6 +46,13 @@ export function renderOverlayToolbar(registration, context, toolbarContext, opti
|
|
|
46
46
|
{
|
|
47
47
|
element: overlay,
|
|
48
48
|
mount: "after-buttons",
|
|
49
|
+
// A frameless overlay draws its own surface over the content and
|
|
50
|
+
// positions itself, so the content's box has to be its containing
|
|
51
|
+
// block. A shelled tool is `position: fixed` and clamps to the
|
|
52
|
+
// viewport, so it stays where the toolbar puts it.
|
|
53
|
+
...(options.surface === "frameless"
|
|
54
|
+
? { container: "content-boundary" }
|
|
55
|
+
: {}),
|
|
49
56
|
...(options.shell
|
|
50
57
|
? {
|
|
51
58
|
shell: {
|
|
@@ -34,8 +34,6 @@ export const graphToolRegistration = {
|
|
|
34
34
|
pnpSupportIds: [
|
|
35
35
|
"graph", // QTI 3.0 standard (assessment.graph)
|
|
36
36
|
"graphingCalculator", // QTI 3.0 standard (assessment.graphingCalculator)
|
|
37
|
-
"coordinatePlane", // Common variant
|
|
38
|
-
"graphingTool", // Common variant
|
|
39
37
|
],
|
|
40
38
|
/**
|
|
41
39
|
* Pass 2: Graph is relevant when math content is present
|
|
@@ -74,8 +72,6 @@ export const periodicTableToolRegistration = {
|
|
|
74
72
|
// Maps to QTI 3.0 standard feature: periodicTable
|
|
75
73
|
pnpSupportIds: [
|
|
76
74
|
"periodicTable", // QTI 3.0 standard (assessment.periodicTable)
|
|
77
|
-
"chemistryReference", // Common variant
|
|
78
|
-
"elementReference", // Common variant
|
|
79
75
|
],
|
|
80
76
|
/**
|
|
81
77
|
* Pass 2: Periodic table is relevant when science content is present
|
|
@@ -86,8 +86,6 @@ export const ttsToolRegistration = {
|
|
|
86
86
|
pnpSupportIds: [
|
|
87
87
|
"textToSpeech", // QTI 3.0 standard (auditory.textToSpeech)
|
|
88
88
|
"readAloud", // QTI 3.0 standard (auditory.readAloud)
|
|
89
|
-
"tts", // Common abbreviation
|
|
90
|
-
"speechOutput", // Common variant
|
|
91
89
|
],
|
|
92
90
|
/**
|
|
93
91
|
* Pass 2: Determine if TTS is relevant in this context
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-default-tool-loaders",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.70",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Composition layer for the packaged PIE assessment tools: registrations, tag map, placement presets, universal supports and lazy module loaders",
|
|
6
6
|
"repository": {
|
|
@@ -33,23 +33,26 @@
|
|
|
33
33
|
"test": "bun test"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@pie-players/pie-assessment-toolkit": "0.3.
|
|
37
|
-
"@pie-players/pie-players-shared": "0.3.
|
|
38
|
-
"@pie-players/pie-tool-annotation-toolbar": "0.3.
|
|
39
|
-
"@pie-players/pie-tool-answer-eliminator": "0.3.
|
|
40
|
-
"@pie-players/pie-tool-calculator-desmos": "0.3.
|
|
41
|
-
"@pie-players/pie-tool-
|
|
42
|
-
"@pie-players/pie-tool-
|
|
43
|
-
"@pie-players/pie-tool-
|
|
44
|
-
"@pie-players/pie-tool-
|
|
45
|
-
"@pie-players/pie-tool-
|
|
46
|
-
"@pie-players/pie-tool-
|
|
47
|
-
"@pie-players/pie-tool-
|
|
48
|
-
"@pie-players/pie-tool-
|
|
49
|
-
"@pie-players/pie-tool-
|
|
36
|
+
"@pie-players/pie-assessment-toolkit": "0.3.70",
|
|
37
|
+
"@pie-players/pie-players-shared": "0.3.70",
|
|
38
|
+
"@pie-players/pie-tool-annotation-toolbar": "0.3.70",
|
|
39
|
+
"@pie-players/pie-tool-answer-eliminator": "0.3.70",
|
|
40
|
+
"@pie-players/pie-tool-calculator-desmos": "0.3.70",
|
|
41
|
+
"@pie-players/pie-tool-calculator-cortex": "0.3.70",
|
|
42
|
+
"@pie-players/pie-tool-calculator-geogebra": "0.3.70",
|
|
43
|
+
"@pie-players/pie-tool-calculator-shared": "0.3.70",
|
|
44
|
+
"@pie-players/pie-tool-dictionary": "0.3.70",
|
|
45
|
+
"@pie-players/pie-tool-graph": "0.3.70",
|
|
46
|
+
"@pie-players/pie-tool-line-reader": "0.3.70",
|
|
47
|
+
"@pie-players/pie-tool-periodic-table": "0.3.70",
|
|
48
|
+
"@pie-players/pie-tool-picture-dictionary": "0.3.70",
|
|
49
|
+
"@pie-players/pie-tool-protractor": "0.3.70",
|
|
50
|
+
"@pie-players/pie-tool-ruler": "0.3.70",
|
|
51
|
+
"@pie-players/pie-tool-theme": "0.3.70",
|
|
52
|
+
"@pie-players/pie-tool-tts-inline": "0.3.70"
|
|
50
53
|
},
|
|
51
54
|
"devDependencies": {
|
|
52
|
-
"@biomejs/biome": "^2.5.
|
|
55
|
+
"@biomejs/biome": "^2.5.11",
|
|
53
56
|
"typescript": "^5.9.3"
|
|
54
57
|
},
|
|
55
58
|
"homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/default-tool-loaders#readme",
|