@pie-players/pie-default-tool-loaders 0.3.75 → 1.0.0-beta.0
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 +89 -70
- package/dist/calculator-providers/CortexToolProvider.d.ts +0 -2
- package/dist/calculator-providers/CortexToolProvider.js +0 -13
- package/dist/calculator-providers/DesmosToolProvider.d.ts +0 -2
- package/dist/calculator-providers/DesmosToolProvider.js +0 -13
- package/dist/calculator-providers/GeoGebraToolProvider.d.ts +0 -2
- package/dist/calculator-providers/GeoGebraToolProvider.js +0 -13
- package/dist/calculator-providers/LazyCalculatorToolProvider.d.ts +2 -3
- package/dist/calculator-providers/LazyCalculatorToolProvider.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/packaged-capability-composition.d.ts +5 -1
- package/dist/packaged-capability-composition.js +3 -7
- package/dist/registrations/accessibility-tools.js +5 -9
- package/dist/registrations/audio-transcript.d.ts +7 -6
- package/dist/registrations/audio-transcript.js +12 -7
- package/dist/registrations/calculator.js +8 -8
- package/dist/registrations/interaction-tools.js +2 -5
- package/dist/registrations/overlay-toolbar-render.d.ts +8 -11
- package/dist/registrations/overlay-toolbar-render.js +8 -11
- package/dist/registrations/tts.d.ts +1 -2
- package/dist/registrations/tts.js +9 -27
- package/package.json +20 -20
package/README.md
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
# PIE Default Tool Loaders
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
The packaged PIE assessment tools: which capabilities exist in a deployment, how
|
|
4
|
+
they load, and which of them a program grants to everyone. This README is for
|
|
5
|
+
host integrators choosing a tool set and a calculator, and for contributors
|
|
6
|
+
adding a packaged capability.
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
(`pie-calculator-cortex`, `-desmos` and `-geogebra`) so toolkit core
|
|
8
|
-
dependency-light and cycle-safe
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
It owns five things, all answers to "which capabilities does this deployment have
|
|
13
|
-
and how does the program tier them":
|
|
8
|
+
The package owns the concrete `pie-tool-*` dependencies and the calculator
|
|
9
|
+
engines (`pie-calculator-cortex`, `-desmos` and `-geogebra`), so toolkit core
|
|
10
|
+
stays dependency-light and cycle-safe. Core knows the concepts — support ids,
|
|
11
|
+
placement levels, activation kinds and precedence rules — and no concrete
|
|
12
|
+
capability id. A support id is the tool id a profile grants.
|
|
14
13
|
|
|
15
14
|
| Export | What it decides |
|
|
16
15
|
| --- | --- |
|
|
@@ -19,48 +18,54 @@ and how does the program tier them":
|
|
|
19
18
|
| `SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT` | Where they appear and in what order |
|
|
20
19
|
| `createUniversalPersonalNeedsProfile`, `createEmptyPersonalNeedsProfile` | Which of them the program grants to everyone, or to no one |
|
|
21
20
|
| `DEFAULT_TOOL_MODULE_LOADERS` | When each one's bundle loads |
|
|
21
|
+
| `CONTENT_ALTERNATE_REGISTRATIONS` | Which of them carry an authored alternate that renders as a region; the print player mounts these |
|
|
22
22
|
|
|
23
|
-
The individual registrations are exported too, so a host can compose its own
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
These exports are projections of one internal **Packaged Capability
|
|
27
|
-
Composition**. Each packaged capability is authored once with its registration,
|
|
28
|
-
element delivery, module loader, preferred placement and explicit
|
|
29
|
-
universal-support policy. The package build rejects contradictory PIE-owned data
|
|
30
|
-
— for example, a region capability with a toolbar tag, or a content-dependent
|
|
31
|
-
capability marked universal — so release tests find a missing facet
|
|
32
|
-
instead of a learner finding a dead affordance. The browser does not repeat that
|
|
33
|
-
strict gate at import time: a PIE authoring defect must block publication, not an
|
|
34
|
-
otherwise usable assessment.
|
|
35
|
-
|
|
36
|
-
That invariant boundary does not make host input stricter: lazy module loading
|
|
37
|
-
is opt-in, registration/tag/factory overrides take precedence, an empty
|
|
38
|
-
`toolIds` array selects the full packaged set, and unknown selected ids are
|
|
39
|
-
ignored while known ids register.
|
|
23
|
+
The individual registrations are exported too, so a host can compose its own
|
|
24
|
+
set ([Custom sets](#custom-sets)).
|
|
40
25
|
|
|
41
26
|
## Usage
|
|
42
27
|
|
|
43
28
|
```ts
|
|
44
|
-
import {
|
|
45
|
-
createPackagedToolRegistry,
|
|
46
|
-
DEFAULT_TOOL_MODULE_LOADERS,
|
|
47
|
-
} from "@pie-players/pie-default-tool-loaders";
|
|
29
|
+
import { createPackagedToolRegistry } from "@pie-players/pie-default-tool-loaders";
|
|
48
30
|
|
|
49
31
|
// The packaged capability set, lazily loaded.
|
|
50
|
-
const registry = createPackagedToolRegistry(
|
|
51
|
-
|
|
52
|
-
|
|
32
|
+
const registry = createPackagedToolRegistry();
|
|
33
|
+
|
|
34
|
+
// The same registrations for a host that defines the tool elements itself.
|
|
35
|
+
const preloaded = createPackagedToolRegistry({ toolModuleLoaders: {} });
|
|
53
36
|
```
|
|
54
37
|
|
|
55
38
|
One loader set serves every host shape. `DEFAULT_TOOL_MODULE_LOADERS` holds a
|
|
56
|
-
loader per packaged capability
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
39
|
+
loader per packaged capability and is what `createPackagedToolRegistry`
|
|
40
|
+
installs unless `toolModuleLoaders` replaces it. A registry loads a module only
|
|
41
|
+
when a tool first renders, so an item player, a section player and an
|
|
42
|
+
assessment player share the set and load only the tools they place.
|
|
43
|
+
|
|
44
|
+
`createPackagedToolRegistry` is lenient with host input. Registration, tag-map
|
|
45
|
+
and component-factory overrides take precedence over the packaged data. An
|
|
46
|
+
empty `toolIds` array selects the full packaged set, and unknown ids in it are
|
|
47
|
+
ignored while the known ones register.
|
|
48
|
+
|
|
49
|
+
## Calculator providers
|
|
50
|
+
|
|
51
|
+
The calculator is one element, `<pie-tool-calculator>`, for every provider. The
|
|
52
|
+
toolkit picks the provider from `tools.providers.calculator` when the element
|
|
53
|
+
mounts, and an open calculator remounts on the new provider when a tool-config
|
|
54
|
+
update replaces it.
|
|
55
|
+
|
|
56
|
+
Desmos is the provider when none is configured, and it needs an API key: pass
|
|
57
|
+
it through `provider.runtime.authFetcher`, a `provider.init.proxyEndpoint` that
|
|
58
|
+
returns it, or `provider.init.apiKey` in development
|
|
59
|
+
([Calculator with host auth](../../docs/tools-and-accomodations/tool_provider_system.md#calculator-with-host-auth)).
|
|
60
|
+
Without one the calculator fails to load. For a keyless, offline-capable
|
|
61
|
+
calculator with no runtime CDN, use `provider.id: "calculator-cortex"`. Its
|
|
62
|
+
`settings` take the `CortexCalculatorSettings` type that
|
|
63
|
+
`@pie-players/pie-calculator-cortex` exports: `angleMode`,
|
|
64
|
+
`calculationPrecision`, `displayPrecision`, `historyLimit`,
|
|
65
|
+
`evaluationTimeLimitMs`, `allowedFunctions`, `allowClipboard`, `messages`,
|
|
66
|
+
`direction` and `graph`. Clipboard blocking follows `restrictedMode`;
|
|
67
|
+
`allowClipboard` alone blocks nothing. The [Cortex README](../calculator-cortex/README.md)
|
|
68
|
+
covers localization, message overrides and the keypad.
|
|
64
69
|
|
|
65
70
|
```ts
|
|
66
71
|
const tools = {
|
|
@@ -76,10 +81,7 @@ const tools = {
|
|
|
76
81
|
};
|
|
77
82
|
```
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
`provider.id: "calculator-cortex"`. Its `settings` accept angle mode, precision,
|
|
81
|
-
history, evaluation limit, allowed functions, clipboard policy, and graph
|
|
82
|
-
viewport options documented by `@pie-players/pie-calculator-cortex`.
|
|
84
|
+
## Custom sets
|
|
83
85
|
|
|
84
86
|
A host composing its own set starts from the toolkit's empty `ToolRegistry`,
|
|
85
87
|
registers into it, and installs the tag map its registrations create elements
|
|
@@ -105,19 +107,21 @@ A later `setToolModuleLoaders` call adds or replaces entries. A replacement
|
|
|
105
107
|
registered after a tool's module has loaded is ignored with a warning, since the
|
|
106
108
|
elements it defines are already in place.
|
|
107
109
|
|
|
108
|
-
## Content-dependent capabilities
|
|
110
|
+
## Content-dependent capabilities
|
|
109
111
|
|
|
110
|
-
A content-dependent capability
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
`
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
A content-dependent capability declares `requiresAuthoredContent`: it renders
|
|
113
|
+
only where the content carries what it needs, and
|
|
114
|
+
`createUniversalPersonalNeedsProfile()` never grants one. It ships in
|
|
115
|
+
`PACKAGED_TOOL_REGISTRATIONS` only when it has a useful presentation path
|
|
116
|
+
without a grant and declares `resolvesWithoutGrant`. Audio transcript is the
|
|
117
|
+
shipped example: an authored `visibility: "always"` transcript reaches every
|
|
118
|
+
player, while its accommodation path stays policy-gated and `transcript` stays
|
|
119
|
+
out of the universal profile.
|
|
116
120
|
|
|
117
|
-
A content-dependent capability with no
|
|
118
|
-
|
|
119
|
-
`@pie-players/pie-tool-sign-language` and register it,
|
|
120
|
-
|
|
121
|
+
A content-dependent capability with no such path is an explicit deployment
|
|
122
|
+
choice. Signing is the shipped example: install
|
|
123
|
+
`@pie-players/pie-tool-sign-language` and register it, the same two lines a
|
|
124
|
+
host writes for a capability of its own.
|
|
121
125
|
|
|
122
126
|
```ts
|
|
123
127
|
import { signLanguageRegistration } from "@pie-players/pie-tool-sign-language";
|
|
@@ -129,25 +133,40 @@ registry.register(signLanguageRegistration);
|
|
|
129
133
|
|
|
130
134
|
`createUniversalPersonalNeedsProfile()` builds a fresh `PersonalNeedsProfile`
|
|
131
135
|
granting the tool ids of the capabilities the packaged set treats as universal
|
|
132
|
-
features.
|
|
136
|
+
features. Tool policy reads the profile from the assessment entity, so set it
|
|
137
|
+
there: on the player's `assessment` property, or through
|
|
138
|
+
`coordinator.updateAssessment(...)` on a coordinator you pass. A
|
|
139
|
+
`section.personalNeedsProfile` is ignored with a console warning.
|
|
133
140
|
|
|
134
141
|
```ts
|
|
135
142
|
import { createUniversalPersonalNeedsProfile } from "@pie-players/pie-default-tool-loaders";
|
|
136
143
|
|
|
137
|
-
|
|
138
|
-
...
|
|
144
|
+
sectionPlayer.assessment = {
|
|
145
|
+
...authoredAssessment,
|
|
139
146
|
personalNeedsProfile: createUniversalPersonalNeedsProfile(),
|
|
140
147
|
};
|
|
141
148
|
```
|
|
142
149
|
|
|
143
150
|
The toolkit ships no populated default, and `createEmptyPersonalNeedsProfile()`
|
|
144
|
-
builds a profile granting nothing. Which capabilities a
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
engages on
|
|
153
|
-
alone decides which tools appear.
|
|
151
|
+
builds a profile granting nothing. Which capabilities a deployment grants by
|
|
152
|
+
default is a property of the program: TTS is a universal feature in one program
|
|
153
|
+
and a documented accommodation in another. The universal profile is data to
|
|
154
|
+
adopt, extend or replace alongside the district and test-administration
|
|
155
|
+
configuration, and it excludes every capability that declares a content
|
|
156
|
+
dependency.
|
|
157
|
+
|
|
158
|
+
An assessment carrying no profile is left alone. `pnpEnforcement`
|
|
159
|
+
auto-detection engages only on host policy material, so with no profile,
|
|
160
|
+
placement alone decides which tools appear.
|
|
161
|
+
|
|
162
|
+
## Packaged capability composition
|
|
163
|
+
|
|
164
|
+
The exports are projections of one internal composition. Each packaged
|
|
165
|
+
capability is authored once with its registration, element delivery, module
|
|
166
|
+
loader, preferred placement and explicit universal-support flag.
|
|
167
|
+
|
|
168
|
+
The package build rejects contradictory PIE-owned data, such as a region
|
|
169
|
+
capability with a toolbar tag or a content-dependent capability marked
|
|
170
|
+
universal, so release tests catch a missing facet before it ships. The browser
|
|
171
|
+
skips that strict check at import time: a PIE authoring defect blocks
|
|
172
|
+
publication and never an otherwise usable assessment.
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
/** Fully bundled open-source calculator adapter for the tool-provider registry. */
|
|
2
2
|
import type { CalculatorToolProviderInitConfig, LazyCalculatorProviderDefinition } from "./LazyCalculatorToolProvider.js";
|
|
3
3
|
import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
|
|
4
|
-
import type { ToolProviderCapabilities } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
5
4
|
export type CortexToolProviderConfig = CalculatorToolProviderInitConfig;
|
|
6
5
|
export declare class CortexToolProvider extends LazyCalculatorToolProvider<CortexToolProviderConfig> {
|
|
7
6
|
readonly providerName = "PIE Open-Source Calculator";
|
|
8
7
|
readonly version = "1";
|
|
9
8
|
readonly requiresAuth = false;
|
|
10
9
|
protected getDefinition(): LazyCalculatorProviderDefinition<CortexToolProviderConfig>;
|
|
11
|
-
getCapabilities(): ToolProviderCapabilities;
|
|
12
10
|
}
|
|
@@ -15,17 +15,4 @@ export class CortexToolProvider extends LazyCalculatorToolProvider {
|
|
|
15
15
|
initializationErrorMessage: "Failed to initialize the PIE open-source calculator provider. Confirm that this browser supports module workers and that the bundled worker assets are available.",
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
getCapabilities() {
|
|
19
|
-
return {
|
|
20
|
-
supportsOffline: true,
|
|
21
|
-
requiresAuth: false,
|
|
22
|
-
maxInstances: null,
|
|
23
|
-
features: {
|
|
24
|
-
basic: true,
|
|
25
|
-
scientific: true,
|
|
26
|
-
graphing: true,
|
|
27
|
-
fourFunction: true,
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
18
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** Desmos calculator adapter for the generic tool-provider registry. */
|
|
2
2
|
import type { CalculatorProviderInit } from "@pie-players/pie-calculator";
|
|
3
3
|
import { LazyCalculatorToolProvider, type LazyCalculatorProviderDefinition } from "./LazyCalculatorToolProvider.js";
|
|
4
|
-
import type { ToolProviderCapabilities } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
5
4
|
/** Provider initialization is the provider-neutral calculator contract. */
|
|
6
5
|
export type DesmosToolProviderConfig = CalculatorProviderInit;
|
|
7
6
|
export declare class DesmosToolProvider extends LazyCalculatorToolProvider<DesmosToolProviderConfig> {
|
|
@@ -9,5 +8,4 @@ export declare class DesmosToolProvider extends LazyCalculatorToolProvider<Desmo
|
|
|
9
8
|
readonly version = "1.12";
|
|
10
9
|
readonly requiresAuth = true;
|
|
11
10
|
protected getDefinition(): LazyCalculatorProviderDefinition<DesmosToolProviderConfig>;
|
|
12
|
-
getCapabilities(): ToolProviderCapabilities;
|
|
13
11
|
}
|
|
@@ -15,17 +15,4 @@ export class DesmosToolProvider extends LazyCalculatorToolProvider {
|
|
|
15
15
|
initializationErrorMessage: "Failed to initialize Desmos calculator provider. Check the application key, preloaded API, runtime endpoint, or network access.",
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
getCapabilities() {
|
|
19
|
-
return {
|
|
20
|
-
supportsOffline: false,
|
|
21
|
-
requiresAuth: true,
|
|
22
|
-
maxInstances: null,
|
|
23
|
-
features: {
|
|
24
|
-
basic: true,
|
|
25
|
-
scientific: true,
|
|
26
|
-
graphing: true,
|
|
27
|
-
fourFunction: true,
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
18
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** GeoGebra calculator adapter for the generic tool-provider registry. */
|
|
2
2
|
import type { CalculatorToolProviderInitConfig, LazyCalculatorProviderDefinition } from "./LazyCalculatorToolProvider.js";
|
|
3
3
|
import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
|
|
4
|
-
import type { ToolProviderCapabilities } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
5
4
|
export interface GeoGebraToolProviderConfig extends CalculatorToolProviderInitConfig {
|
|
6
5
|
scriptUrl?: string;
|
|
7
6
|
appletTimeoutMs?: number;
|
|
@@ -11,5 +10,4 @@ export declare class GeoGebraToolProvider extends LazyCalculatorToolProvider<Geo
|
|
|
11
10
|
readonly version = "6";
|
|
12
11
|
readonly requiresAuth = false;
|
|
13
12
|
protected getDefinition(): LazyCalculatorProviderDefinition<GeoGebraToolProviderConfig>;
|
|
14
|
-
getCapabilities(): ToolProviderCapabilities;
|
|
15
13
|
}
|
|
@@ -15,17 +15,4 @@ export class GeoGebraToolProvider extends LazyCalculatorToolProvider {
|
|
|
15
15
|
initializationErrorMessage: "Failed to initialize GeoGebra calculator provider. Confirm that the deployment may load GeoGebra and that its script URL is reachable.",
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
getCapabilities() {
|
|
19
|
-
return {
|
|
20
|
-
supportsOffline: false,
|
|
21
|
-
requiresAuth: false,
|
|
22
|
-
maxInstances: null,
|
|
23
|
-
features: {
|
|
24
|
-
basic: true,
|
|
25
|
-
scientific: true,
|
|
26
|
-
graphing: true,
|
|
27
|
-
fourFunction: false,
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
18
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CalculatorProvider, CalculatorProviderInit } from "@pie-players/pie-calculator";
|
|
2
|
-
import type { ToolProviderApi
|
|
2
|
+
import type { ToolProviderApi } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
3
3
|
export type CalculatorToolProviderInitConfig = Pick<CalculatorProviderInit, "onTelemetry">;
|
|
4
4
|
type InitializableCalculatorProvider<TConfig> = CalculatorProvider & {
|
|
5
5
|
initialize(config: TConfig): Promise<void>;
|
|
@@ -12,7 +12,7 @@ export interface LazyCalculatorProviderDefinition<TConfig> {
|
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Shared lazy-module and lifecycle implementation for calculator tool adapters.
|
|
15
|
-
* Concrete adapters own only their metadata
|
|
15
|
+
* Concrete adapters own only their metadata and provider import.
|
|
16
16
|
*/
|
|
17
17
|
export declare abstract class LazyCalculatorToolProvider<TConfig extends CalculatorToolProviderInitConfig> implements ToolProviderApi<CalculatorProvider> {
|
|
18
18
|
abstract readonly providerName: string;
|
|
@@ -20,7 +20,6 @@ export declare abstract class LazyCalculatorToolProvider<TConfig extends Calcula
|
|
|
20
20
|
abstract readonly version: string;
|
|
21
21
|
abstract readonly requiresAuth: boolean;
|
|
22
22
|
protected abstract getDefinition(): LazyCalculatorProviderDefinition<TConfig>;
|
|
23
|
-
abstract getCapabilities(): ToolProviderCapabilities;
|
|
24
23
|
private calculatorProvider;
|
|
25
24
|
private initializationPromise;
|
|
26
25
|
private lifecycleGeneration;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared lazy-module and lifecycle implementation for calculator tool adapters.
|
|
3
|
-
* Concrete adapters own only their metadata
|
|
3
|
+
* Concrete adapters own only their metadata and provider import.
|
|
4
4
|
*/
|
|
5
5
|
export class LazyCalculatorToolProvider {
|
|
6
6
|
category = "calculator";
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export type { PackagedToolRegistryOptions } from "./packaged-capability-composit
|
|
|
2
2
|
export { createEmptyPersonalNeedsProfile, createPackagedToolRegistry, createUniversalPersonalNeedsProfile, DEFAULT_TOOL_MODULE_LOADERS, PACKAGED_TOOL_REGISTRATIONS, PACKAGED_TOOL_TAG_MAP, SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT, } 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
|
-
export { AUDIO_TRANSCRIPT_FEATURE_ID, AUDIO_TRANSCRIPT_REGION_CLASS, AUDIO_TRANSCRIPT_REGION_LABEL, audioTranscriptRegistration, resolveAudioTranscript, type ResolvedAudioTranscript, } from "./registrations/audio-transcript.js";
|
|
5
|
+
export { AUDIO_TRANSCRIPT_FEATURE_ID, AUDIO_TRANSCRIPT_REGION_CLASS, AUDIO_TRANSCRIPT_REGION_LABEL, audioTranscriptRegistration, CONTENT_LEAD_SURFACE, resolveAudioTranscript, type ResolvedAudioTranscript, } from "./registrations/audio-transcript.js";
|
|
6
6
|
export { calculatorToolRegistration } from "./registrations/calculator.js";
|
|
7
7
|
export { createDictionaryToolRegistration, createPictureDictionaryToolRegistration, dictionaryToolRegistration, type DictionaryVariantOptions, pictureDictionaryToolRegistration, spanishDictionaryToolRegistration, spanishPictureDictionaryToolRegistration, } from "./registrations/dictionary-tools.js";
|
|
8
8
|
export { answerEliminatorToolRegistration } from "./registrations/interaction-tools.js";
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ export { CONTENT_ALTERNATE_REGISTRATIONS } from "./content-alternates.js";
|
|
|
5
5
|
// Individual registrations, for a host composing a subset rather than the whole
|
|
6
6
|
// packaged set.
|
|
7
7
|
export { annotationToolbarRegistration, lineReaderToolRegistration, themeToolRegistration, } from "./registrations/accessibility-tools.js";
|
|
8
|
-
export { AUDIO_TRANSCRIPT_FEATURE_ID, AUDIO_TRANSCRIPT_REGION_CLASS, AUDIO_TRANSCRIPT_REGION_LABEL, audioTranscriptRegistration, resolveAudioTranscript, } from "./registrations/audio-transcript.js";
|
|
8
|
+
export { AUDIO_TRANSCRIPT_FEATURE_ID, AUDIO_TRANSCRIPT_REGION_CLASS, AUDIO_TRANSCRIPT_REGION_LABEL, audioTranscriptRegistration, CONTENT_LEAD_SURFACE, resolveAudioTranscript, } from "./registrations/audio-transcript.js";
|
|
9
9
|
export { calculatorToolRegistration } from "./registrations/calculator.js";
|
|
10
10
|
export { createDictionaryToolRegistration, createPictureDictionaryToolRegistration, dictionaryToolRegistration, pictureDictionaryToolRegistration, spanishDictionaryToolRegistration, spanishPictureDictionaryToolRegistration, } from "./registrations/dictionary-tools.js";
|
|
11
11
|
export { answerEliminatorToolRegistration } from "./registrations/interaction-tools.js";
|
|
@@ -16,7 +16,11 @@ export interface PackagedToolRegistryOptions {
|
|
|
16
16
|
toolTagMap?: Partial<ToolTagMap>;
|
|
17
17
|
/** Override the component factory per tool. */
|
|
18
18
|
toolComponentFactories?: Partial<ToolComponentFactoryMap>;
|
|
19
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Module loaders keyed by toolId, each loading its tool's element on first
|
|
21
|
+
* render. Defaults to `DEFAULT_TOOL_MODULE_LOADERS`; a map replaces it, so a
|
|
22
|
+
* host that defines its tool elements itself passes `{}`.
|
|
23
|
+
*/
|
|
20
24
|
toolModuleLoaders?: Partial<Record<string, ToolModuleLoader>>;
|
|
21
25
|
/** Restrict registration to specific packaged tool ids. */
|
|
22
26
|
toolIds?: string[];
|
|
@@ -248,13 +248,9 @@ class PackagedCapabilityComposition {
|
|
|
248
248
|
for (const registration of this.selectRegistrations(options.toolIds)) {
|
|
249
249
|
registry.register(options.overrides?.[registration.toolId] ?? registration);
|
|
250
250
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if (options.toolModuleLoaders &&
|
|
255
|
-
Object.keys(options.toolModuleLoaders).length > 0) {
|
|
256
|
-
registry.setToolModuleLoaders({ ...options.toolModuleLoaders });
|
|
257
|
-
}
|
|
251
|
+
registry.setToolModuleLoaders({
|
|
252
|
+
...(options.toolModuleLoaders ?? this.moduleLoaders),
|
|
253
|
+
});
|
|
258
254
|
registry.setComponentOverrides({
|
|
259
255
|
toolTagMap: {
|
|
260
256
|
...this.toolTagMap,
|
|
@@ -23,7 +23,6 @@ export const lineReaderToolRegistration = {
|
|
|
23
23
|
nameKey: "tools.lineReader.name",
|
|
24
24
|
descriptionKey: "tools.lineReader.description",
|
|
25
25
|
icon: "bars-3",
|
|
26
|
-
// Line reader appears where there's text to read
|
|
27
26
|
supportedLevels: ["section", "passage", "rubric", "item"],
|
|
28
27
|
/**
|
|
29
28
|
* Pass 2: Line reader is relevant when readable text is present
|
|
@@ -56,7 +55,7 @@ export const themeToolRegistration = {
|
|
|
56
55
|
* Pass 2: Color scheme is always relevant when allowed
|
|
57
56
|
*/
|
|
58
57
|
isVisibleInContext(context) {
|
|
59
|
-
return true;
|
|
58
|
+
return true;
|
|
60
59
|
},
|
|
61
60
|
renderToolbar(context, toolbarContext) {
|
|
62
61
|
return renderOverlayToolbar(this, context, toolbarContext, {
|
|
@@ -86,15 +85,12 @@ export const annotationToolbarRegistration = {
|
|
|
86
85
|
activation: "selection-gateway",
|
|
87
86
|
singletonScope: "section",
|
|
88
87
|
/**
|
|
89
|
-
* Section-scoped singleton surface. The
|
|
90
|
-
* `
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* moves that wiring into this registration, and the renderer discovers it
|
|
94
|
-
* through `ToolRegistry.getToolsBySurface("section-overlay")`.
|
|
88
|
+
* Section-scoped singleton surface. The renderer discovers it through
|
|
89
|
+
* `ToolRegistry.getToolsBySurface("section-overlay")`, so the section player
|
|
90
|
+
* names no tool id and a host can contribute another section-scoped
|
|
91
|
+
* capability.
|
|
95
92
|
*/
|
|
96
93
|
surfaces: ["section-overlay"],
|
|
97
|
-
// Annotation appears where there's text content
|
|
98
94
|
supportedLevels: ["passage", "rubric", "item", "element"],
|
|
99
95
|
/**
|
|
100
96
|
* Pass 2: Annotation is relevant when readable text is present
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* Two kinds of content wear the same shape, and the card says which:
|
|
6
6
|
*
|
|
7
7
|
* - `visibility: "always"` is authored presentation. The item family was
|
|
8
|
-
* designed to be delivered with its transcript on screen —
|
|
9
|
-
*
|
|
10
|
-
* revokes it.
|
|
8
|
+
* designed to be delivered with its transcript on screen — sentence items in
|
|
9
|
+
* an early-literacy assessment, for instance — so no profile grants it and
|
|
10
|
+
* none revokes it.
|
|
11
11
|
* - anything else, `"onGrant"` included, is the accommodation. Policy decides
|
|
12
|
-
* against the `transcript` support id, and silence means no. For
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* against the `transcript` support id, and silence means no. For item
|
|
13
|
+
* families where a visible transcript turns the item into a reading task,
|
|
14
|
+
* that gate is the whole point.
|
|
15
15
|
*
|
|
16
16
|
* The toolkit renders the text, not the element. Before this, the transcript rode
|
|
17
17
|
* on `model.audioTranscript` and `mc-populated-blank` revealed its own copy when
|
|
@@ -47,6 +47,7 @@ export declare const AUDIO_TRANSCRIPT_REGION_CLASS = "pie-tool-audio-transcript"
|
|
|
47
47
|
export interface ResolvedAudioTranscript {
|
|
48
48
|
catalogId: string;
|
|
49
49
|
text: string;
|
|
50
|
+
/** BCP 47, as the region's `lang` takes it, whatever syntax the card used. */
|
|
50
51
|
language?: string;
|
|
51
52
|
/** True when the card declares itself authored presentation. */
|
|
52
53
|
always: boolean;
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* Two kinds of content wear the same shape, and the card says which:
|
|
6
6
|
*
|
|
7
7
|
* - `visibility: "always"` is authored presentation. The item family was
|
|
8
|
-
* designed to be delivered with its transcript on screen —
|
|
9
|
-
*
|
|
10
|
-
* revokes it.
|
|
8
|
+
* designed to be delivered with its transcript on screen — sentence items in
|
|
9
|
+
* an early-literacy assessment, for instance — so no profile grants it and
|
|
10
|
+
* none revokes it.
|
|
11
11
|
* - anything else, `"onGrant"` included, is the accommodation. Policy decides
|
|
12
|
-
* against the `transcript` support id, and silence means no. For
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* against the `transcript` support id, and silence means no. For item
|
|
13
|
+
* families where a visible transcript turns the item into a reading task,
|
|
14
|
+
* that gate is the whole point.
|
|
15
15
|
*
|
|
16
16
|
* The toolkit renders the text, not the element. Before this, the transcript rode
|
|
17
17
|
* on `model.audioTranscript` and `mc-populated-blank` revealed its own copy when
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
* absent from the universal preset — a content-dependent support never belongs in
|
|
36
36
|
* a wholesale grant.
|
|
37
37
|
*/
|
|
38
|
+
import { toLanguageTag } from "@pie-players/pie-players-shared/i18n/language-tags";
|
|
38
39
|
/** QTI 3.0 / AfA support id gating an audio transcript. */
|
|
39
40
|
export const AUDIO_TRANSCRIPT_FEATURE_ID = "transcript";
|
|
40
41
|
/** Catalog type carrying the transcript text. */
|
|
@@ -55,6 +56,10 @@ const isTranscriptCard = (card) => !!card && card.catalog === AUDIO_TRANSCRIPT_C
|
|
|
55
56
|
const isAlwaysVisible = (card) => typeof card.visibility === "string" &&
|
|
56
57
|
card.visibility.trim().toLowerCase() === ALWAYS_VISIBLE;
|
|
57
58
|
const cardText = (card) => typeof card.content === "string" ? card.content.trim() : "";
|
|
59
|
+
// The Learnosity transform emits POSIX `es_ES`, which `lang` does not accept.
|
|
60
|
+
const cardLanguage = (card) => typeof card.language === "string"
|
|
61
|
+
? toLanguageTag(card.language) || undefined
|
|
62
|
+
: undefined;
|
|
58
63
|
/**
|
|
59
64
|
* The transcript an entity carries, or `null`.
|
|
60
65
|
*
|
|
@@ -83,7 +88,7 @@ export function resolveAudioTranscript(context) {
|
|
|
83
88
|
const resolved = {
|
|
84
89
|
catalogId,
|
|
85
90
|
text,
|
|
86
|
-
language:
|
|
91
|
+
language: cardLanguage(card),
|
|
87
92
|
always: isAlwaysVisible(card),
|
|
88
93
|
};
|
|
89
94
|
// An `always` card answers whether or not policy granted anything, so it
|
|
@@ -54,7 +54,10 @@ function normalizeCalculatorType(value) {
|
|
|
54
54
|
}
|
|
55
55
|
function getCalculatorRenderParams(toolbarContext) {
|
|
56
56
|
const params = toolbarContext.getToolRenderParams?.("calculator") ?? {};
|
|
57
|
-
|
|
57
|
+
// A host resolver or a request names the type; the policy parameters'
|
|
58
|
+
// `type` is the default beneath both.
|
|
59
|
+
const calculatorType = normalizeCalculatorType(params.calculatorType) ??
|
|
60
|
+
normalizeCalculatorType(toolbarContext.getToolParameters?.("calculator")?.type);
|
|
58
61
|
const availableTypesRaw = params.availableTypes;
|
|
59
62
|
const availableTypes = Array.isArray(availableTypesRaw)
|
|
60
63
|
? availableTypesRaw
|
|
@@ -135,7 +138,6 @@ export const calculatorToolRegistration = {
|
|
|
135
138
|
* (MathML, LaTeX, arithmetic markers).
|
|
136
139
|
*/
|
|
137
140
|
isVisibleInContext(context) {
|
|
138
|
-
// Show only when math is present in item content.
|
|
139
141
|
return hasMathContent(context);
|
|
140
142
|
},
|
|
141
143
|
renderToolbar(context, toolbarContext) {
|
|
@@ -156,8 +158,7 @@ export const calculatorToolRegistration = {
|
|
|
156
158
|
icon: typeof this.icon === "function" ? this.icon(context) : this.icon,
|
|
157
159
|
// Routes this button through <nds-icon-button> where the host enables NDS
|
|
158
160
|
// icons. Declared here because which capabilities render in the host's
|
|
159
|
-
// design system is a composition decision
|
|
160
|
-
// the `calculator` toolId, which put a capability name in the generic core.
|
|
161
|
+
// design system is a composition decision.
|
|
161
162
|
faIconName: "calculator",
|
|
162
163
|
disabled: false,
|
|
163
164
|
// The name stays put across open and closed. The toolbar mirrors
|
|
@@ -248,10 +249,9 @@ export const calculatorToolRegistration = {
|
|
|
248
249
|
const active = toolbarContext.isToolVisible(this.toolId);
|
|
249
250
|
button.active = active;
|
|
250
251
|
button.label = displayName;
|
|
251
|
-
// Static across the toggle
|
|
252
|
-
//
|
|
253
|
-
//
|
|
254
|
-
// `aria-pressed` already carries.
|
|
252
|
+
// Static across the toggle: `aria-pressed` carries the state, and a
|
|
253
|
+
// "Close …" template built from a localized noun mixes languages
|
|
254
|
+
// ("Close rekenmachine" under nl-NL).
|
|
255
255
|
button.ariaLabel = displayName;
|
|
256
256
|
button.tooltip = displayName;
|
|
257
257
|
if (lastVisibleState !== active) {
|
|
@@ -8,7 +8,7 @@ import { hasChoiceInteraction } from "@pie-players/pie-assessment-toolkit/tools/
|
|
|
8
8
|
import { createToolElement, } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
9
9
|
import { createScopedVisibilityBinding, syncButtonAndOverlayVisibility, } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
10
10
|
import { resolveOverlayElement } from "./overlay-element-cache.js";
|
|
11
|
-
/** `
|
|
11
|
+
/** The policy parameters' `strategy`, defaulting to strikethrough. */
|
|
12
12
|
const normalizeEliminationStrategy = (value) => value === "mask" ? "mask" : "strikethrough";
|
|
13
13
|
/** The state-store key of each PIE element in the item, by model id. */
|
|
14
14
|
function resolveElementStateKeys(context, toolbarContext) {
|
|
@@ -38,7 +38,6 @@ export const answerEliminatorToolRegistration = {
|
|
|
38
38
|
nameKey: "tools.answerEliminator.name",
|
|
39
39
|
descriptionKey: "tools.answerEliminator.description",
|
|
40
40
|
icon: "strikethrough",
|
|
41
|
-
// Answer eliminator appears at item level only
|
|
42
41
|
supportedLevels: ["item"],
|
|
43
42
|
/**
|
|
44
43
|
* Pass 2: Answer eliminator is relevant only for choice-based questions
|
|
@@ -61,9 +60,8 @@ export const answerEliminatorToolRegistration = {
|
|
|
61
60
|
const visibility = createScopedVisibilityBinding(this.toolId, toolbarContext);
|
|
62
61
|
const componentOverrides = toolbarContext.componentOverrides ?? {};
|
|
63
62
|
const overlay = resolveOverlayElement(toolbarContext, visibility.fullToolId, () => createToolElement(this.toolId, context, toolbarContext, componentOverrides));
|
|
64
|
-
overlay.setAttribute("tool-id", visibility.fullToolId);
|
|
65
63
|
overlay.setAttribute("button-alignment", "inline");
|
|
66
|
-
overlay.setAttribute("strategy", normalizeEliminationStrategy(toolbarContext.
|
|
64
|
+
overlay.setAttribute("strategy", normalizeEliminationStrategy(toolbarContext.getToolParameters?.("answerEliminator")?.strategy));
|
|
67
65
|
const button = {
|
|
68
66
|
toolId: this.toolId,
|
|
69
67
|
label: this.name,
|
|
@@ -84,7 +82,6 @@ export const answerEliminatorToolRegistration = {
|
|
|
84
82
|
overlay,
|
|
85
83
|
isActive: visibility.isActive,
|
|
86
84
|
});
|
|
87
|
-
overlay.scopeElement = toolbarContext.getScopeElement?.() || null;
|
|
88
85
|
overlay.elementStateKeys = resolveElementStateKeys(context, toolbarContext);
|
|
89
86
|
},
|
|
90
87
|
subscribeActive: visibility.subscribeActive,
|
|
@@ -2,18 +2,15 @@
|
|
|
2
2
|
* The `renderToolbar` shape shared by every packaged capability that puts one
|
|
3
3
|
* overlay behind one toolbar button.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* sync — was identical, which is why one rule landing in three spellings was
|
|
10
|
-
* possible: the shell title was `resolveToolRegistrationName` in two files,
|
|
11
|
-
* `displayName` in a third and a raw `t(key)` in a fourth.
|
|
5
|
+
* What varies between capabilities is the two options below: whether the overlay
|
|
6
|
+
* paints its own chrome or takes a draggable window, and that window's size. The
|
|
7
|
+
* visibility binding, the button, the component-override lookup, the `tool-id`
|
|
8
|
+
* attribute and the sync are shared, so the shell title has one spelling.
|
|
12
9
|
*
|
|
13
|
-
* Catalog keys are derived from `toolId
|
|
14
|
-
* `tools.<toolId>.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* Catalog keys are derived from `toolId`: `tools.<toolId>.buttonA11y` and
|
|
11
|
+
* `tools.<toolId>.tooltip`. A capability needing a different prefix — the
|
|
12
|
+
* dictionary variants, which compose several capabilities off one element —
|
|
13
|
+
* keeps its own renderer.
|
|
17
14
|
*/
|
|
18
15
|
import { type ToolContext, type ToolRegistration, type ToolToolbarRenderResult, type ToolbarContext } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
19
16
|
/** A window's geometry. Absent for overlays that paint their own chrome. */
|
|
@@ -2,18 +2,15 @@
|
|
|
2
2
|
* The `renderToolbar` shape shared by every packaged capability that puts one
|
|
3
3
|
* overlay behind one toolbar button.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* sync — was identical, which is why one rule landing in three spellings was
|
|
10
|
-
* possible: the shell title was `resolveToolRegistrationName` in two files,
|
|
11
|
-
* `displayName` in a third and a raw `t(key)` in a fourth.
|
|
5
|
+
* What varies between capabilities is the two options below: whether the overlay
|
|
6
|
+
* paints its own chrome or takes a draggable window, and that window's size. The
|
|
7
|
+
* visibility binding, the button, the component-override lookup, the `tool-id`
|
|
8
|
+
* attribute and the sync are shared, so the shell title has one spelling.
|
|
12
9
|
*
|
|
13
|
-
* Catalog keys are derived from `toolId
|
|
14
|
-
* `tools.<toolId>.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* Catalog keys are derived from `toolId`: `tools.<toolId>.buttonA11y` and
|
|
11
|
+
* `tools.<toolId>.tooltip`. A capability needing a different prefix — the
|
|
12
|
+
* dictionary variants, which compose several capabilities off one element —
|
|
13
|
+
* keeps its own renderer.
|
|
17
14
|
*/
|
|
18
15
|
import { applyOverlaySurface, createScopedVisibilityBinding, createToolElement, resolveToolRegistrationName, syncButtonAndOverlayVisibility, } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
19
16
|
import { resolveOverlayElement } from "./overlay-element-cache.js";
|
|
@@ -4,13 +4,12 @@
|
|
|
4
4
|
* Registers the TTS tool for reading content aloud.
|
|
5
5
|
*/
|
|
6
6
|
import type { ToolRegistration } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
7
|
-
export declare const TOOL_ACTIVE_CHANGE_EVENT = "pie-tool-active-change";
|
|
8
7
|
/**
|
|
9
8
|
* Text-to-Speech tool registration
|
|
10
9
|
*
|
|
11
10
|
* Supports:
|
|
12
11
|
* - Reading content aloud using browser TTS or external providers
|
|
13
12
|
* - Context-aware visibility (shows when readable text is available)
|
|
14
|
-
* -
|
|
13
|
+
* - Item and passage levels
|
|
15
14
|
*/
|
|
16
15
|
export declare const ttsToolRegistration: ToolRegistration;
|
|
@@ -3,22 +3,21 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Registers the TTS tool for reading content aloud.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import { createScopedToolId, createToolElement, } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
8
|
-
import { buildRuntimeTTSConfig,
|
|
6
|
+
import { hasSpokenContent } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
7
|
+
import { createScopedToolId, createToolElement, TOOL_ACTIVE_CHANGE_EVENT, } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
8
|
+
import { buildRuntimeTTSConfig, normalizeTTSSpeedControlOptions, resolveTTSHostToolbarLayout, resolveTTSRuntimeSettings, } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
9
9
|
import { TTSToolProvider } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
10
10
|
import { resolveOverlayElement } from "./overlay-element-cache.js";
|
|
11
11
|
// This package owns the server adapter's import, so the toolkit never names it
|
|
12
12
|
// and a bundler building the toolkit alone has nothing to resolve.
|
|
13
13
|
const loadServerTTSProvider = async () => (await import("@pie-players/tts-client-server")).ServerTTSProvider;
|
|
14
|
-
export const TOOL_ACTIVE_CHANGE_EVENT = "pie-tool-active-change";
|
|
15
14
|
/**
|
|
16
15
|
* Text-to-Speech tool registration
|
|
17
16
|
*
|
|
18
17
|
* Supports:
|
|
19
18
|
* - Reading content aloud using browser TTS or external providers
|
|
20
19
|
* - Context-aware visibility (shows when readable text is available)
|
|
21
|
-
* -
|
|
20
|
+
* - Item and passage levels
|
|
22
21
|
*/
|
|
23
22
|
export const ttsToolRegistration = {
|
|
24
23
|
toolId: "textToSpeech",
|
|
@@ -46,9 +45,6 @@ export const ttsToolRegistration = {
|
|
|
46
45
|
const normalizedConfig = {
|
|
47
46
|
...config,
|
|
48
47
|
};
|
|
49
|
-
if ("layoutMode" in normalizedConfig) {
|
|
50
|
-
normalizedConfig.layoutMode = normalizeTTSLayoutMode(normalizedConfig.layoutMode);
|
|
51
|
-
}
|
|
52
48
|
if ("speedOptions" in normalizedConfig) {
|
|
53
49
|
normalizedConfig.speedOptions = normalizeTTSSpeedControlOptions(normalizedConfig.speedOptions);
|
|
54
50
|
}
|
|
@@ -59,11 +55,10 @@ export const ttsToolRegistration = {
|
|
|
59
55
|
/**
|
|
60
56
|
* Pass 2: Determine if TTS is relevant in this context
|
|
61
57
|
*
|
|
62
|
-
* TTS is relevant when
|
|
63
|
-
* - Context contains readable text (at least 10 characters)
|
|
58
|
+
* TTS is relevant when the context holds readable text or a catalog idref.
|
|
64
59
|
*/
|
|
65
60
|
isVisibleInContext(context) {
|
|
66
|
-
return
|
|
61
|
+
return hasSpokenContent(context);
|
|
67
62
|
},
|
|
68
63
|
renderToolbar(context, toolbarContext) {
|
|
69
64
|
const resolveRuntimeSettings = () => resolveTTSRuntimeSettings(toolbarContext.toolkitCoordinator?.getToolConfig(this.toolId) ||
|
|
@@ -72,19 +67,7 @@ export const ttsToolRegistration = {
|
|
|
72
67
|
const runtimeSettings = resolveRuntimeSettings();
|
|
73
68
|
return normalizeTTSSpeedControlOptions(runtimeSettings.speedOptions);
|
|
74
69
|
};
|
|
75
|
-
const resolveLayoutMode = () => resolveTTSLayoutMode(resolveRuntimeSettings());
|
|
76
|
-
const resolveHostLayout = () => resolveTTSHostToolbarLayout(resolveRuntimeSettings());
|
|
77
70
|
const fullToolId = createScopedToolId(this.toolId, toolbarContext.scope.level, toolbarContext.scope.scopeId);
|
|
78
|
-
// Only a language the toolbar or its host named: unnamed, the control resolves
|
|
79
|
-
// markup `lang`, and the browser voice follows the browser's language.
|
|
80
|
-
const applyContentLanguage = (element) => {
|
|
81
|
-
if (toolbarContext.language) {
|
|
82
|
-
element.setAttribute("language", toolbarContext.language);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
element.removeAttribute("language");
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
71
|
const resolveControlSize = () => {
|
|
89
72
|
const raw = toolbarContext.ui?.size;
|
|
90
73
|
return raw === "sm" || raw === "lg" ? raw : "md";
|
|
@@ -92,22 +75,21 @@ export const ttsToolRegistration = {
|
|
|
92
75
|
const element = resolveOverlayElement(toolbarContext, fullToolId, () => createToolElement(this.toolId, context, toolbarContext, toolbarContext.componentOverrides));
|
|
93
76
|
const applyAttributes = () => {
|
|
94
77
|
element.setAttribute("catalog-id", toolbarContext.catalogId || toolbarContext.itemId);
|
|
95
|
-
applyContentLanguage(element);
|
|
96
78
|
element.setAttribute("size", resolveControlSize());
|
|
97
|
-
element.setAttribute("layout-mode",
|
|
79
|
+
element.setAttribute("layout-mode", resolveRuntimeSettings().layoutMode);
|
|
98
80
|
element.speedOptions = resolveElementSpeedOptions();
|
|
99
81
|
element.showSingleSpeedOption =
|
|
100
82
|
resolveRuntimeSettings().showSingleSpeedOption === true;
|
|
101
83
|
};
|
|
102
84
|
applyAttributes();
|
|
103
|
-
const hostLayout =
|
|
85
|
+
const hostLayout = resolveTTSHostToolbarLayout(resolveRuntimeSettings());
|
|
104
86
|
return {
|
|
105
87
|
toolId: this.toolId,
|
|
106
88
|
button: null,
|
|
107
89
|
elements: [
|
|
108
90
|
{
|
|
109
91
|
element,
|
|
110
|
-
mount:
|
|
92
|
+
mount: "before-buttons",
|
|
111
93
|
layoutHints: {
|
|
112
94
|
controlsRow: {
|
|
113
95
|
reserveSpace: hostLayout.controlsRow.reserveSpace,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-default-tool-loaders",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-beta.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Composition layer for the packaged PIE assessment tools: registrations, tag map, placement preset, universal and empty profiles, and lazy module loaders",
|
|
6
6
|
"repository": {
|
|
@@ -33,25 +33,25 @@
|
|
|
33
33
|
"test": "bun test"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@pie-players/pie-assessment-toolkit": "0.
|
|
37
|
-
"@pie-players/pie-calculator": "0.
|
|
38
|
-
"@pie-players/pie-calculator-cortex": "0.
|
|
39
|
-
"@pie-players/pie-calculator-desmos": "0.
|
|
40
|
-
"@pie-players/pie-calculator-geogebra": "0.
|
|
41
|
-
"@pie-players/pie-players-shared": "0.
|
|
42
|
-
"@pie-players/pie-tool-annotation-toolbar": "0.
|
|
43
|
-
"@pie-players/pie-tool-answer-eliminator": "0.
|
|
44
|
-
"@pie-players/pie-tool-calculator-shared": "0.
|
|
45
|
-
"@pie-players/pie-tool-dictionary": "0.
|
|
46
|
-
"@pie-players/pie-tool-graph": "0.
|
|
47
|
-
"@pie-players/pie-tool-line-reader": "0.
|
|
48
|
-
"@pie-players/pie-tool-periodic-table": "0.
|
|
49
|
-
"@pie-players/pie-tool-picture-dictionary": "0.
|
|
50
|
-
"@pie-players/pie-tool-protractor": "0.
|
|
51
|
-
"@pie-players/pie-tool-ruler": "0.
|
|
52
|
-
"@pie-players/pie-tool-theme": "0.
|
|
53
|
-
"@pie-players/pie-tool-tts-inline": "0.
|
|
54
|
-
"@pie-players/tts-client-server": "0.
|
|
36
|
+
"@pie-players/pie-assessment-toolkit": "1.0.0-beta.0",
|
|
37
|
+
"@pie-players/pie-calculator": "1.0.0-beta.0",
|
|
38
|
+
"@pie-players/pie-calculator-cortex": "1.0.0-beta.0",
|
|
39
|
+
"@pie-players/pie-calculator-desmos": "1.0.0-beta.0",
|
|
40
|
+
"@pie-players/pie-calculator-geogebra": "1.0.0-beta.0",
|
|
41
|
+
"@pie-players/pie-players-shared": "1.0.0-beta.0",
|
|
42
|
+
"@pie-players/pie-tool-annotation-toolbar": "1.0.0-beta.0",
|
|
43
|
+
"@pie-players/pie-tool-answer-eliminator": "1.0.0-beta.0",
|
|
44
|
+
"@pie-players/pie-tool-calculator-shared": "1.0.0-beta.0",
|
|
45
|
+
"@pie-players/pie-tool-dictionary": "1.0.0-beta.0",
|
|
46
|
+
"@pie-players/pie-tool-graph": "1.0.0-beta.0",
|
|
47
|
+
"@pie-players/pie-tool-line-reader": "1.0.0-beta.0",
|
|
48
|
+
"@pie-players/pie-tool-periodic-table": "1.0.0-beta.0",
|
|
49
|
+
"@pie-players/pie-tool-picture-dictionary": "1.0.0-beta.0",
|
|
50
|
+
"@pie-players/pie-tool-protractor": "1.0.0-beta.0",
|
|
51
|
+
"@pie-players/pie-tool-ruler": "1.0.0-beta.0",
|
|
52
|
+
"@pie-players/pie-tool-theme": "1.0.0-beta.0",
|
|
53
|
+
"@pie-players/pie-tool-tts-inline": "1.0.0-beta.0",
|
|
54
|
+
"@pie-players/tts-client-server": "1.0.0-beta.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@biomejs/biome": "^2.5.15",
|